From: Hermès Bélusca-Maïto Date: Thu, 13 Dec 2012 00:46:55 +0000 (+0000) Subject: [FREELDR] X-Git-Tag: backups/ros-csrss@60644~104^2~133 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=d4129a2e0748600cf5c201051d1ee1e99007d63c [FREELDR] - Use a list of possible operating system method loading to load ReactOS / ROS-Setup / Windows / Linux or booting from a disk / partition ..., instead of using a (huge) if () else if () ... instruction. - Modify the corresponding functions to take into account for this new functionality. - Allow having a live + boot cd if needed, in a elegant way. svn path=/trunk/; revision=57899 --- diff --git a/reactos/boot/freeldr/freeldr/arch/i386/custom.c b/reactos/boot/freeldr/freeldr/arch/i386/custom.c index 973c32674e1..2e754ece57e 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/custom.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/custom.c @@ -40,8 +40,8 @@ VOID OptionMenuCustomBoot(VOID) "ReactOS", "Linux" }; - ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]); - ULONG SelectedMenuItem; + ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]); + ULONG SelectedMenuItem; if (!UiDisplayMenu("Please choose a boot method:", CustomBootMenuList, @@ -74,10 +74,11 @@ VOID OptionMenuCustomBoot(VOID) VOID OptionMenuCustomBootDisk(VOID) { - CHAR SectionName[100]; - CHAR BootDriveString[20]; - ULONG SectionId; + ULONG_PTR SectionId; + CHAR SectionName[100]; + CHAR BootDriveString[20]; TIMEINFO* TimeInfo; + OperatingSystemItem OperatingSystem; RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); @@ -111,16 +112,21 @@ VOID OptionMenuCustomBootDisk(VOID) UiMessageBox(CustomBootPrompt); - LoadAndBootDrive(SectionName); + OperatingSystem.SystemPartition = SectionName; + OperatingSystem.LoadIdentifier = NULL; + OperatingSystem.OsLoadOptions = NULL; + + LoadAndBootDrive(&OperatingSystem, 0); } VOID OptionMenuCustomBootPartition(VOID) { - CHAR SectionName[100]; - CHAR BootDriveString[20]; - CHAR BootPartitionString[20]; - ULONG SectionId; + ULONG_PTR SectionId; + CHAR SectionName[100]; + CHAR BootDriveString[20]; + CHAR BootPartitionString[20]; TIMEINFO* TimeInfo; + OperatingSystemItem OperatingSystem; RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); @@ -166,17 +172,22 @@ VOID OptionMenuCustomBootPartition(VOID) UiMessageBox(CustomBootPrompt); - LoadAndBootPartition(SectionName); + OperatingSystem.SystemPartition = SectionName; + OperatingSystem.LoadIdentifier = NULL; + OperatingSystem.OsLoadOptions = NULL; + + LoadAndBootPartition(&OperatingSystem, 0); } VOID OptionMenuCustomBootBootSectorFile(VOID) { - CHAR SectionName[100]; - CHAR BootDriveString[20]; - CHAR BootPartitionString[20]; - CHAR BootSectorFileString[200]; - ULONG SectionId; + ULONG_PTR SectionId; + CHAR SectionName[100]; + CHAR BootDriveString[20]; + CHAR BootPartitionString[20]; + CHAR BootSectorFileString[200]; TIMEINFO* TimeInfo; + OperatingSystemItem OperatingSystem; RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); @@ -234,19 +245,24 @@ VOID OptionMenuCustomBootBootSectorFile(VOID) UiMessageBox(CustomBootPrompt); - LoadAndBootBootSector(SectionName); + OperatingSystem.SystemPartition = SectionName; + OperatingSystem.LoadIdentifier = NULL; + OperatingSystem.OsLoadOptions = NULL; + + LoadAndBootBootSector(&OperatingSystem, 0); } VOID OptionMenuCustomBootLinux(VOID) { - CHAR SectionName[100]; - CHAR BootDriveString[20]; - CHAR BootPartitionString[20]; - CHAR LinuxKernelString[200]; - CHAR LinuxInitrdString[200]; - CHAR LinuxCommandLineString[200]; - ULONG SectionId; + ULONG_PTR SectionId; + CHAR SectionName[100]; + CHAR BootDriveString[20]; + CHAR BootPartitionString[20]; + CHAR LinuxKernelString[200]; + CHAR LinuxInitrdString[200]; + CHAR LinuxCommandLineString[200]; TIMEINFO* TimeInfo; + OperatingSystemItem OperatingSystem; RtlZeroMemory(SectionName, sizeof(SectionName)); RtlZeroMemory(BootDriveString, sizeof(BootDriveString)); @@ -331,7 +347,11 @@ VOID OptionMenuCustomBootLinux(VOID) UiMessageBox(CustomBootPrompt); - LoadAndBootLinux(SectionName, "Custom Linux Setup"); + OperatingSystem.SystemPartition = SectionName; + OperatingSystem.LoadIdentifier = "Custom Linux Setup"; + OperatingSystem.OsLoadOptions = NULL; + + LoadAndBootLinux(&OperatingSystem, 0); } VOID OptionMenuReboot(VOID) diff --git a/reactos/boot/freeldr/freeldr/arch/i386/miscboot.c b/reactos/boot/freeldr/freeldr/arch/i386/miscboot.c index 691c297f366..3e7e5f00911 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/miscboot.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/miscboot.c @@ -19,21 +19,24 @@ #include -VOID LoadAndBootBootSector(PCSTR OperatingSystemName) +VOID +LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { - PFILE FilePointer; - CHAR SettingName[80]; - ULONG SectionId; + 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(OperatingSystemName); + UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file - if (!IniOpenSection(OperatingSystemName, &SectionId)) + if (!IniOpenSection(SectionName, &SectionId)) { - sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName); + sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return; } @@ -79,22 +82,25 @@ VOID LoadAndBootBootSector(PCSTR OperatingSystemName) ChainLoadBiosBootSectorCode(); } -VOID LoadAndBootPartition(PCSTR OperatingSystemName) +VOID +LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { + ULONG_PTR SectionId; + PCSTR SectionName = OperatingSystem->SystemPartition; CHAR SettingName[80]; CHAR SettingValue[80]; - ULONG SectionId; PARTITION_TABLE_ENTRY PartitionTableEntry; UCHAR DriveNumber; ULONG PartitionNumber; // Find all the message box settings and run them - UiShowMessageBoxesInSection(OperatingSystemName); + UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file - if (!IniOpenSection(OperatingSystemName, &SectionId)) + if (!IniOpenSection(SectionName, &SectionId)) { - sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName); + sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return; } @@ -151,20 +157,23 @@ VOID LoadAndBootPartition(PCSTR OperatingSystemName) ChainLoadBiosBootSectorCode(); } -VOID LoadAndBootDrive(PCSTR OperatingSystemName) +VOID +LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { + ULONG_PTR SectionId; + PCSTR SectionName = OperatingSystem->SystemPartition; CHAR SettingName[80]; CHAR SettingValue[80]; - ULONG SectionId; UCHAR DriveNumber; // Find all the message box settings and run them - UiShowMessageBoxesInSection(OperatingSystemName); + UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file - if (!IniOpenSection(OperatingSystemName, &SectionId)) + if (!IniOpenSection(SectionName, &SectionId)) { - sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName); + sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return; } diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index 81d28e408f3..bfd6c3587a8 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -24,7 +24,90 @@ ULONG reactos_disk_count = 0; CHAR reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0}; CHAR reactos_arc_strings[32][256]; -ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount) +typedef +VOID +(*OS_LOADING_METHOD)(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); + +struct +{ + CHAR BootType[80]; + USHORT OperatingSystemVersion; + OS_LOADING_METHOD Load; +} OSLoadingMethods[] = +{ +#ifdef FREELDR_REACTOS_SETUP + {"ReactOSSetup", 0 , LoadReactOSSetup }, +#endif + +#ifdef _M_IX86 + {"BootSector" , 0 , LoadAndBootBootSector}, + {"Drive" , 0 , LoadAndBootDrive }, + {"Partition" , 0 , LoadAndBootPartition }, + + {"Linux" , 0 , LoadAndBootLinux }, + + {"Windows" , 0 , LoadAndBootWindows }, + {"WindowsNT40" , _WIN32_WINNT_NT4 , LoadAndBootWindows }, +#endif + {"Windows2003" , _WIN32_WINNT_WS03, LoadAndBootWindows }, + +// {"Not found" , 0 , NULL } +}; + +VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem) +{ + ULONG_PTR SectionId; + PCSTR SectionName = OperatingSystem->SystemPartition; + CHAR BootType[80]; + ULONG i; + + // Try to open the operating system section in the .ini file + if (IniOpenSection(SectionName, &SectionId)) + { + // Try to read the boot type + IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType)); + } + else + { + BootType[0] = ANSI_NULL; + } + + if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL) + { + // Try to infere the boot type value +#ifdef _M_IX86 + ULONG FileId; + if (ArcOpen((PSTR)SectionName, OpenReadOnly, &FileId) == ESUCCESS) + { + ArcClose(FileId); + strcpy(BootType, "BootSector"); + } + else +#endif + { + strcpy(BootType, "Windows"); + } + } + + // Install the drive mapper according to this section drive mappings +#if defined(_M_IX86) && !defined(_MSC_VER) + DriveMapMapDrivesInSection(SectionName); +#endif + + // Loop through the OS loading method table and find a suitable OS to boot + for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i) + { + if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0) + { + OSLoadingMethods[i].Load(OperatingSystem, + OSLoadingMethods[i].OperatingSystemVersion); + return; + } + } +} + +ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount) { CHAR DefaultOSText[80]; PCSTR DefaultOSName; @@ -105,17 +188,14 @@ BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress) VOID RunLoader(VOID) { - CHAR SettingValue[80]; - CHAR BootType[80]; ULONG_PTR SectionId; ULONG OperatingSystemCount; OperatingSystemItem* OperatingSystemList; - PCSTR *OperatingSystemDisplayNames; - PCSTR SectionName; - ULONG i; + PCSTR* OperatingSystemDisplayNames; ULONG DefaultOperatingSystem; LONG TimeOut; ULONG SelectedOperatingSystem; + ULONG i; // FIXME: if possible, only detect and register ARC devices... if (!MachHwDetect()) @@ -206,78 +286,8 @@ VOID RunLoader(VOID) TimeOut = -1; - // Try to open the operating system section in the .ini file - SettingValue[0] = ANSI_NULL; - SectionName = OperatingSystemList[SelectedOperatingSystem].SystemPartition; - if (IniOpenSection(SectionName, &SectionId)) - { - // Try to read the boot type - IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType)); - } - else - BootType[0] = ANSI_NULL; - - if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL) - { - // Try to infere boot type value -#ifdef _M_IX86 - ULONG FileId; - if (ArcOpen((CHAR*)SectionName, OpenReadOnly, &FileId) == ESUCCESS) - { - ArcClose(FileId); - strcpy(BootType, "BootSector"); - } - else -#endif - { - strcpy(BootType, "Windows"); - } - } - - // Get OS setting value - IniOpenSection("Operating Systems", &SectionId); - IniReadSettingByName(SectionId, SectionName, SettingValue, sizeof(SettingValue)); - - // Install the drive mapper according to this sections drive mappings -#if defined(_M_IX86) && !defined(_MSC_VER) - DriveMapMapDrivesInSection(SectionName); -#endif - -#ifdef FREELDR_REACTOS_SETUP - // WinLdr-style boot - LoadReactOSSetup(); -#elif defined(_M_IX86) - if (_stricmp(BootType, "Windows") == 0) - { - LoadAndBootWindows(SectionName, SettingValue, 0); - } - else if (_stricmp(BootType, "WindowsNT40") == 0) - { - LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_NT4); - } - else if (_stricmp(BootType, "Windows2003") == 0) - { - LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_WS03); - } - else if (_stricmp(BootType, "Linux") == 0) - { - LoadAndBootLinux(SectionName, OperatingSystemDisplayNames[SelectedOperatingSystem]); - } - else if (_stricmp(BootType, "BootSector") == 0) - { - LoadAndBootBootSector(SectionName); - } - else if (_stricmp(BootType, "Partition") == 0) - { - LoadAndBootPartition(SectionName); - } - else if (_stricmp(BootType, "Drive") == 0) - { - LoadAndBootDrive(SectionName); - } -#else - LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_WS03); -#endif + // Load the chosen operating system + LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]); } reboot: diff --git a/reactos/boot/freeldr/freeldr/include/arch/i386/miscboot.h b/reactos/boot/freeldr/freeldr/include/arch/i386/miscboot.h index df17f558848..42d31fdbbb9 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/i386/miscboot.h +++ b/reactos/boot/freeldr/freeldr/include/arch/i386/miscboot.h @@ -19,6 +19,12 @@ #pragma once -VOID LoadAndBootBootSector(PCSTR OperatingSystemName); -VOID LoadAndBootPartition(PCSTR OperatingSystemName); -VOID LoadAndBootDrive(PCSTR OperatingSystemName); +VOID +LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); +VOID +LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); +VOID +LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); diff --git a/reactos/boot/freeldr/freeldr/include/linux.h b/reactos/boot/freeldr/freeldr/include/linux.h index 306cf54b695..8f5d5ba368f 100644 --- a/reactos/boot/freeldr/freeldr/include/linux.h +++ b/reactos/boot/freeldr/freeldr/include/linux.h @@ -18,6 +18,7 @@ */ #include +#include #ifndef __LINUX_H #define __LINUX_H @@ -129,7 +130,9 @@ typedef struct VOID BootNewLinuxKernel(VOID); // Implemented in linux.S VOID BootOldLinuxKernel(ULONG KernelSize); // Implemented in linux.S -VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description); +VOID +LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName); BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile); diff --git a/reactos/boot/freeldr/freeldr/include/winldr.h b/reactos/boot/freeldr/freeldr/include/winldr.h index 3a123ea99ba..dd0aa4fdfea 100644 --- a/reactos/boot/freeldr/freeldr/include/winldr.h +++ b/reactos/boot/freeldr/freeldr/include/winldr.h @@ -80,9 +80,8 @@ extern PLOADER_SYSTEM_BLOCK WinLdrSystemBlock; // ReactOS Loading Functions // /////////////////////////////////////////////////////////////////////////////////////// -VOID LoadAndBootWindows(PCSTR OperatingSystemName, - PSTR SettingsValue, - USHORT OperatingSystemVersion); +VOID LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); // conversion.c PVOID VaToPa(PVOID Va); @@ -179,7 +178,9 @@ LoadAndBootWindowsCommon( LPCSTR BootPath, BOOLEAN Setup); -VOID LoadReactOSSetup(VOID); +VOID +LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion); VOID WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock); diff --git a/reactos/boot/freeldr/freeldr/linuxboot.c b/reactos/boot/freeldr/freeldr/linuxboot.c index 5eacc285686..46a750a6a67 100644 --- a/reactos/boot/freeldr/freeldr/linuxboot.c +++ b/reactos/boot/freeldr/freeldr/linuxboot.c @@ -72,8 +72,12 @@ BOOLEAN RemoveQuotes(PCHAR QuotedString) return TRUE; } -VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description) +VOID +LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { + PCSTR SectionName = OperatingSystem->SystemPartition; + PCSTR Description = OperatingSystem->LoadIdentifier; PFILE LinuxKernel = 0; PFILE LinuxInitrdFile = 0; CHAR TempString[260]; @@ -93,7 +97,7 @@ VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description) UiDrawProgressBarCenter(0, 100, LinuxBootDescription); // Parse the .ini file section - if (!LinuxParseIniSection(OperatingSystemName)) + if (!LinuxParseIniSection(SectionName)) { goto LinuxBootFailed; } @@ -235,18 +239,18 @@ LinuxBootFailed: LinuxCommandLineSize = 0; } -BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName) +BOOLEAN LinuxParseIniSection(PCSTR SectionName) { - CHAR SettingName[260]; - ULONG SectionId; + ULONG_PTR SectionId; + CHAR SettingName[260]; // Find all the message box settings and run them - UiShowMessageBoxesInSection(OperatingSystemName); + UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file - if (!IniOpenSection(OperatingSystemName, &SectionId)) + if (!IniOpenSection(SectionName, &SectionId)) { - sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName); + sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return FALSE; } diff --git a/reactos/boot/freeldr/freeldr/windows/setupldr.c b/reactos/boot/freeldr/freeldr/windows/setupldr.c index 3d838c9f514..16a93ed2ea7 100644 --- a/reactos/boot/freeldr/freeldr/windows/setupldr.c +++ b/reactos/boot/freeldr/freeldr/windows/setupldr.c @@ -133,7 +133,9 @@ SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, LPCSTR S } while (InfFindNextLine(&InfContext, &InfContext)); } -VOID LoadReactOSSetup(VOID) +VOID +LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { CHAR FileName[512]; CHAR BootPath[512]; diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index e9d03cfb146..c1b6fa3906e 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -456,22 +456,28 @@ LoadModule( } VOID -LoadAndBootWindows(PCSTR OperatingSystemName, - PSTR SettingsValue, - USHORT OperatingSystemVersion) +LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem, + IN USHORT OperatingSystemVersion) { + ULONG_PTR SectionId; + PCSTR SectionName = OperatingSystem->SystemPartition; + CHAR SettingsValue[80]; BOOLEAN HasSection; - char BootPath[MAX_PATH]; + CHAR BootPath[MAX_PATH]; CHAR FileName[MAX_PATH]; CHAR BootOptions[256]; PCHAR File; BOOLEAN Status; - ULONG_PTR SectionId; PLOADER_PARAMETER_BLOCK LoaderBlock; + // Get OS setting value + SettingsValue[0] = ANSI_NULL; + IniOpenSection("Operating Systems", &SectionId); + IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue)); + // Open the operating system section // specified in the .ini file - HasSection = IniOpenSection(OperatingSystemName, &SectionId); + HasSection = IniOpenSection(SectionName, &SectionId); UiDrawBackdrop(); UiDrawProgressBarCenter(1, 100, "Loading NT..."); @@ -480,7 +486,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath))) { - strcpy(BootPath, OperatingSystemName); + strcpy(BootPath, SectionName); } /* Special case for LiveCD */ @@ -499,7 +505,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions))) { /* Get options after the title */ - const CHAR*p = SettingsValue; + PCSTR p = SettingsValue; while (*p == ' ' || *p == '"') p++; while (*p != '\0' && *p != '"')