[freeldr] Rework operating system menu, by storing each selection in a structure instead of distinct arrays.

As a bonus, entries like LiveCD\reactos="ReactOS" /DEBUGPORT=COM1 /SOS /MININT now work

svn path=/trunk/; revision=44498
This commit is contained in:
Hervé Poussineau 2009-12-09 22:03:39 +00:00
parent 3eb7ba30ee
commit 9dae13cb9a
9 changed files with 236 additions and 273 deletions

View file

@ -19,15 +19,95 @@
#include <freeldr.h>
ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
{
CHAR DefaultOSText[80];
PCSTR DefaultOSName;
ULONG_PTR SectionId;
ULONG DefaultOS = 0;
ULONG Idx;
if (!IniOpenSection("FreeLoader", &SectionId))
{
return 0;
}
DefaultOSName = CmdLineGetDefaultOS();
if (NULL == DefaultOSName)
{
if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
if (NULL != DefaultOSName)
{
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
{
DefaultOS = Idx;
break;
}
}
}
return DefaultOS;
}
LONG GetTimeOut(VOID)
{
CHAR TimeOutText[20];
LONG TimeOut;
ULONG_PTR SectionId;
TimeOut = CmdLineGetTimeOut();
if (0 <= TimeOut)
{
return TimeOut;
}
if (!IniOpenSection("FreeLoader", &SectionId))
{
return -1;
}
if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
{
TimeOut = atoi(TimeOutText);
}
else
{
TimeOut = -1;
}
return TimeOut;
}
BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
{
if (KeyPress == KEY_F8)
{
DoOptionsMenu();
return TRUE;
}
// We didn't handle the key
return FALSE;
}
VOID RunLoader(VOID)
{
CHAR SettingValue[80];
CHAR BootType[80];
ULONG_PTR SectionId;
ULONG OperatingSystemCount;
PCSTR *OperatingSystemSectionNames;
OperatingSystemItem* OperatingSystemList;
PCSTR *OperatingSystemDisplayNames;
PCSTR SectionName;
ULONG i;
ULONG DefaultOperatingSystem;
LONG TimeOut;
ULONG SelectedOperatingSystem;
@ -58,10 +138,10 @@ VOID RunLoader(VOID)
return;
}
if (!InitOperatingSystemList(&OperatingSystemSectionNames, &OperatingSystemDisplayNames, &OperatingSystemCount))
OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount);
if (!OperatingSystemList)
{
UiMessageBox("Press ENTER to reboot.");
UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
goto reboot;
}
@ -71,7 +151,20 @@ VOID RunLoader(VOID)
goto reboot;
}
DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemSectionNames, OperatingSystemCount);
DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList, OperatingSystemCount);
//
// Create list of display names
//
OperatingSystemDisplayNames = MmHeapAlloc(sizeof(PCSTR) * OperatingSystemCount);
if (!OperatingSystemDisplayNames)
{
goto reboot;
}
for (i = 0; i < OperatingSystemCount; i++)
{
OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier;
}
//
// Find all the message box settings and run them
@ -95,7 +188,7 @@ VOID RunLoader(VOID)
// Try to open the operating system section in the .ini file
SettingValue[0] = ANSI_NULL;
SectionName = OperatingSystemSectionNames[SelectedOperatingSystem];
SectionName = OperatingSystemList[SelectedOperatingSystem].SystemPartition;
if (IniOpenSection(SectionName, &SectionId))
{
// Try to read the boot type
@ -185,82 +278,3 @@ reboot:
UiUnInitialize("Rebooting...");
return;
}
ULONG GetDefaultOperatingSystem(PCSTR OperatingSystemList[], ULONG OperatingSystemCount)
{
CHAR DefaultOSText[80];
PCSTR DefaultOSName;
ULONG_PTR SectionId;
ULONG DefaultOS = 0;
ULONG Idx;
if (!IniOpenSection("FreeLoader", &SectionId))
{
return 0;
}
DefaultOSName = CmdLineGetDefaultOS();
if (NULL == DefaultOSName)
{
if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
{
DefaultOSName = DefaultOSText;
}
}
if (NULL != DefaultOSName)
{
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
if (_stricmp(DefaultOSName, OperatingSystemList[Idx]) == 0)
{
DefaultOS = Idx;
break;
}
}
}
return DefaultOS;
}
LONG GetTimeOut(VOID)
{
CHAR TimeOutText[20];
LONG TimeOut;
ULONG_PTR SectionId;
TimeOut = CmdLineGetTimeOut();
if (0 <= TimeOut)
{
return TimeOut;
}
if (!IniOpenSection("FreeLoader", &SectionId))
{
return -1;
}
if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
{
TimeOut = atoi(TimeOutText);
}
else
{
TimeOut = -1;
}
return TimeOut;
}
BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
{
if (KeyPress == KEY_F8)
{
DoOptionsMenu();
return TRUE;
}
// We didn't handle the key
return FALSE;
}

View file

@ -0,0 +1,43 @@
/*
* FreeLoader
* Copyright (C) 2009 Hervé Poussineau <hpoussin@reactos.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* component.c */
CONFIGURATION_COMPONENT* ArcGetChild(CONFIGURATION_COMPONENT *Current);
CONFIGURATION_COMPONENT* ArcGetParent(CONFIGURATION_COMPONENT *Current);
CONFIGURATION_COMPONENT* ArcGetPeer(CONFIGURATION_COMPONENT *Current);
CONFIGURATION_COMPONENT*
ArcAddChild(
CONFIGURATION_COMPONENT *Current,
CONFIGURATION_COMPONENT *Template,
VOID *ConfigurationData);
LONG
ArcDeleteComponent(
CONFIGURATION_COMPONENT *ComponentToDelete);
LONG
ArcGetConfigurationData(
VOID* ConfigurationData,
CONFIGURATION_COMPONENT* Component);
/* mm.c */
MEMORY_DESCRIPTOR*
ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current);
/* time.c */
TIMEINFO* ArcGetTime(VOID);
ULONG ArcGetRelativeTime(VOID);

View file

@ -1,29 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __BOOTMGR_H
#define __BOOTMGR_H
ULONG GetDefaultOperatingSystem(PCSTR OperatingSystemList[], ULONG OperatingSystemCount);
LONG GetTimeOut(VOID);
BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress);
#endif // #defined __BOOTMGR_H

View file

@ -43,6 +43,7 @@
#include <stdio.h>
#include <ctype.h>
#include <rosldr.h>
#include <arcemul.h>
#include <arch.h>
#include <rtl.h>
#include <disk.h>
@ -97,7 +98,6 @@
#include <bget.h>
#include <winerror.h>
/* Needed by boot manager */
#include <bootmgr.h>
#include <oslist.h>
#include <options.h>
#include <linux.h>

View file

@ -100,9 +100,6 @@ BOOLEAN MachDiskNormalizeSystemPath(char *SystemPath, unsigned Size);
BOOLEAN MachDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
BOOLEAN MachDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry);
ULONG MachDiskGetCacheableBlockCount(ULONG DriveNumber);
TIMEINFO* ArcGetTime(VOID);
ULONG ArcGetRelativeTime(VOID);
VOID MachHwDetect(VOID);
VOID MachPrepareForReactOS(IN BOOLEAN Setup);
#define MachConsPutChar(Ch) MachVtbl.ConsPutChar(Ch)

View file

@ -20,9 +20,13 @@
#ifndef __OSLIST_H
#define __OSLIST_H
BOOLEAN InitOperatingSystemList(PCSTR **SectionNamesPointer, PCSTR **DisplayNamesPointer, ULONG* OperatingSystemCountPointer);
ULONG CountOperatingSystems(ULONG SectionId);
BOOLEAN AllocateListMemory(PCHAR **SectionNamesPointer, PCHAR **DisplayNamesPointer, ULONG OperatingSystemCount);
BOOLEAN RemoveQuotes(PCHAR QuotedString);
typedef struct tagOperatingSystemItem
{
PCSTR SystemPartition;
PCSTR LoadIdentifier;
PCSTR OsLoadOptions;
} OperatingSystemItem;
OperatingSystemItem* InitOperatingSystemList(ULONG* OperatingSystemCountPointer);
#endif // #defined __OSLIST_H

View file

@ -41,6 +41,36 @@ PVOID LinuxInitrdLoadAddress = NULL;
CHAR LinuxBootDescription[80];
CHAR LinuxBootPath[260] = "";
BOOLEAN RemoveQuotes(PCHAR QuotedString)
{
CHAR TempString[200];
PCHAR p;
PSTR Start;
//
// Skip spaces up to "
//
p = QuotedString;
while (*p == ' ' || *p == '"')
p++;
Start = p;
//
// Go up to next "
//
while (*p != '"' && *p != ANSI_NULL)
p++;
*p = ANSI_NULL;
//
// Copy result
//
strcpy(TempString, Start);
strcpy(QuotedString, TempString);
return TRUE;
}
VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description)
{
PFILE LinuxKernel = 0;

View file

@ -41,7 +41,6 @@
#undef MachDiskReadLogicalSectors
#undef MachDiskGetDriveGeometry
#undef MachDiskGetCacheableBlockCount
#undef MachHwDetect
MACHVTBL MachVtbl;
@ -177,10 +176,4 @@ MachDiskGetCacheableBlockCount(ULONG DriveNumber)
return MachVtbl.DiskGetCacheableBlockCount(DriveNumber);
}
VOID
MachHwDetect(VOID)
{
MachVtbl.HwDetect();
}
/* EOF */

View file

@ -19,179 +19,90 @@
#include <freeldr.h>
BOOLEAN InitOperatingSystemList(PCSTR **SectionNamesPointer, PCSTR **DisplayNamesPointer, ULONG* OperatingSystemCountPointer)
static PCSTR CopyString(PCSTR Source)
{
ULONG Idx;
ULONG CurrentOperatingSystemIndex;
CHAR SettingName[260];
CHAR SettingValue[260];
ULONG OperatingSystemCount;
ULONG_PTR SectionId;
ULONG SectionSettingCount;
PCHAR *OperatingSystemSectionNames;
PCHAR *OperatingSystemDisplayNames;
PSTR Dest;
if (!Source)
return NULL;
Dest = MmHeapAlloc(strlen(Source) + 1);
if (Dest)
{
strcpy(Dest, Source);
}
return Dest;
}
OperatingSystemItem* InitOperatingSystemList(ULONG* OperatingSystemCountPointer)
{
ULONG Idx;
CHAR SettingName[260];
CHAR SettingValue[260];
ULONG_PTR SectionId;
PCHAR TitleStart, TitleEnd;
PCSTR OsLoadOptions;
ULONG Count;
OperatingSystemItem* Items;
//
// Open the [FreeLoader] section
//
if (!IniOpenSection("Operating Systems", &SectionId))
{
UiMessageBox("Section [Operating Systems] not found in freeldr.ini.");
return FALSE;
return NULL;
}
SectionSettingCount = IniGetNumSectionItems(SectionId);
OperatingSystemCount = CountOperatingSystems(SectionId);
//
// Count number of operating systems in the section
//
Count = IniGetNumSectionItems(SectionId);
//
// Allocate memory to hold operating system lists
//
if (!AllocateListMemory(&OperatingSystemSectionNames, &OperatingSystemDisplayNames, OperatingSystemCount))
Items = MmHeapAlloc(Count * sizeof(OperatingSystemItem));
if (!Items)
{
return FALSE;
return NULL;
}
//
// Now loop through and read the operating system section and display names
//
CurrentOperatingSystemIndex = 0;
for (Idx=0; Idx<SectionSettingCount; Idx++)
for (Idx = 0; Idx < Count; Idx++)
{
IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue));
// Copy the section name
strcpy(OperatingSystemSectionNames[CurrentOperatingSystemIndex], SettingName);
// Copy the display name
RemoveQuotes(SettingValue);
strcpy(OperatingSystemDisplayNames[CurrentOperatingSystemIndex], SettingValue);
CurrentOperatingSystemIndex++;
}
*OperatingSystemCountPointer = OperatingSystemCount;
*SectionNamesPointer = (PCSTR*)OperatingSystemSectionNames;
*DisplayNamesPointer = (PCSTR*)OperatingSystemDisplayNames;
return TRUE;
}
ULONG CountOperatingSystems(ULONG SectionId)
{
return IniGetNumSectionItems(SectionId);
}
BOOLEAN AllocateListMemory(PCHAR **SectionNamesPointer, PCHAR **DisplayNamesPointer, ULONG OperatingSystemCount)
{
ULONG Idx;
PCHAR *OperatingSystemSectionNames = NULL;
PCHAR *OperatingSystemDisplayNames = NULL;
//
// Allocate memory to hold operating system list arrays
//
OperatingSystemSectionNames = MmHeapAlloc( sizeof(PCHAR) * OperatingSystemCount);
OperatingSystemDisplayNames = MmHeapAlloc( sizeof(PCHAR) * OperatingSystemCount);
//
// If either allocation failed then return FALSE
//
if ( (OperatingSystemSectionNames == NULL) || (OperatingSystemDisplayNames == NULL) )
{
if (OperatingSystemSectionNames != NULL)
//
// Search start and end of the title
//
OsLoadOptions = NULL;
TitleStart = SettingValue;
while (*TitleStart == ' ' || *TitleStart == '"')
TitleStart++;
TitleEnd = TitleStart;
if (*TitleEnd != ANSI_NULL)
TitleEnd++;
while (*TitleEnd != ANSI_NULL && *TitleEnd != '"')
TitleEnd++;
if (*TitleEnd != ANSI_NULL)
{
MmHeapFree(OperatingSystemSectionNames);
*TitleEnd = ANSI_NULL;
OsLoadOptions = TitleEnd + 1;
}
if (OperatingSystemDisplayNames != NULL)
{
MmHeapFree(OperatingSystemDisplayNames);
}
return FALSE;
}
//
// Clear our newly allocated memory
//
memset(OperatingSystemSectionNames, 0, sizeof(PCHAR) * OperatingSystemCount);
memset(OperatingSystemDisplayNames, 0, sizeof(PCHAR) * OperatingSystemCount);
//
// Loop through each array element and allocate it's string memory
//
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
OperatingSystemSectionNames[Idx] = MmHeapAlloc(80);
OperatingSystemDisplayNames[Idx] = MmHeapAlloc(80);
//
// If it failed then jump to the cleanup code
// Copy the system partition, identifier and options
//
if ( (OperatingSystemSectionNames[Idx] == NULL) || (OperatingSystemDisplayNames[Idx] == NULL))
{
goto AllocateListMemoryFailed;
}
}
*SectionNamesPointer = OperatingSystemSectionNames;
*DisplayNamesPointer = OperatingSystemDisplayNames;
return TRUE;
AllocateListMemoryFailed:
//
// Loop through each array element and free it's string memory
//
for (Idx=0; Idx<OperatingSystemCount; Idx++)
{
if (OperatingSystemSectionNames[Idx] != NULL)
{
MmHeapFree(OperatingSystemSectionNames[Idx]);
}
if (OperatingSystemDisplayNames[Idx] != NULL)
{
MmHeapFree(OperatingSystemDisplayNames[Idx]);
}
Items[Idx].SystemPartition = CopyString(SettingName);
Items[Idx].LoadIdentifier = CopyString(TitleStart);
Items[Idx].OsLoadOptions = CopyString(OsLoadOptions);
}
//
// Free operating system list arrays
// Return success
//
MmHeapFree(OperatingSystemSectionNames);
MmHeapFree(OperatingSystemDisplayNames);
return FALSE;
}
BOOLEAN RemoveQuotes(PCHAR QuotedString)
{
CHAR TempString[200];
PCHAR p;
PSTR Start;
//
// Skip spaces up to "
//
p = QuotedString;
while (*p == ' ' || *p == '"')
p++;
Start = p;
//
// Go up to next "
//
while (*p != '"' && *p != ANSI_NULL)
p++;
*p = ANSI_NULL;
//
// Copy result
//
strcpy(TempString, Start);
strcpy(QuotedString, TempString);
return TRUE;
*OperatingSystemCountPointer = Count;
return Items;
}