/** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtldr/config.c * DESCRIPTION: XT Boot Loader Configuration * DEVELOPERS: Rafal Kupiec * Jozef Nagy */ #include /** * Parses configuration INI file contents. * * @param FileContents * Supplies a pointer to a wide string containing contents of the configuration file. * * @param Sections * Supplies a pointer to a linked list which will be written by this routine. * * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL XTSTATUS BlConfigParseIniFile(IN PWCHAR FileContents, OUT PLIST_ENTRY Sections) { PWCHAR Argument, LastArg, CurrentSectionName; SIZE_T Length; /* Set a default section name */ CurrentSectionName = L"Unknown"; /* Tokenize provided options */ Argument = RtlWideStringTokenize(FileContents, L"\r\n", &LastArg); /* Iterate over all arguments passed to boot loader */ while(Argument != NULL) { /* Check every line */ if(RtlWideStringCompare(Argument, L"[", 1) == 0) { /* Skip to the section name */ Argument += 1; Length = RtlWideStringLength(Argument, 0); /* Everything until ']' belongs to the section's name */ // CurrentSectionName = RtlWideStringTokenize(Argument, L"]", &LastArg); BlConsolePrint(L"New section: %S\n", CurrentSectionName); } else if(RtlWideStringCompare(Argument, L"Default=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; Length = RtlWideStringLength(Argument, 0); /* Set a default section */ BlConsolePrint(L"Setting DEFAULT value to %S\n", Argument); } else if(RtlWideStringCompare(Argument, L"Debug=", 6) == 0) { /* Skip to the argument value */ Argument += 6; Length = RtlWideStringLength(Argument, 0); /* Set a debug port and baud rate */ BlConsolePrint(L"Setting DEBUG value to %S\n", Argument); } else if(RtlWideStringCompare(Argument, L"Theme=", 6) == 0) { /* Skip to the argument value */ Argument += 6; Length = RtlWideStringLength(Argument, 0); /* Set a theme name */ BlConsolePrint(L"Setting THEME value to %S\n", Argument); } else if(RtlWideStringCompare(Argument, L"Timeout=", 8) == 0) { /* Skip to the argument value */ Argument += 8; Length = RtlWideStringLength(Argument, 0); /* Set a timeout */ BlConsolePrint(L"Setting TIMEOUT value to %S\n", Argument); } else if(RtlWideStringCompare(Argument, L"Tune=", 5) == 0) { /* Skip to the argument value */ Argument += 5; Length = RtlWideStringLength(Argument, 0); /* Set a tune */ BlConsolePrint(L"Setting TUNE value to %S\n", Argument); } else if(RtlWideStringCompare(Argument, L"#", 1) == 0) { /* We can safely ignore a comment */ Argument += 1; } else { /* Configuration file might be corrupt */ BlConsolePrint(L"Unknown argument: %S\n", Argument); return STATUS_INVALID_PARAMETER; } /* Take next argument */ Argument = RtlWideStringTokenize(NULL, L"\n", &LastArg); } return STATUS_SUCCESS; } /** * Parses command line arguments and updates global configuration. * * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL VOID BlpConfigParseCommandLine(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; EFI_STATUS Status; /* Handle loaded image protocol */ Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); if(Status == STATUS_EFI_SUCCESS) { /* Check if launched from UEFI shell */ if(LoadedImage && LoadedImage->LoadOptions) { /* Update global boot loader configuration */ BlpConfigUpdateGlobalConfiguration(LoadedImage->LoadOptions); } } } /** * Updates XTLDR configuration based on provided options. * * @param Options * Supplies a formatted list of options to be processed and stored in global configuration. * * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL VOID BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options) { PWCHAR Argument, LastArg; SIZE_T Length; /* Tokenize provided options */ Argument = RtlWideStringTokenize(Options, L" ", &LastArg); /* Iterate over all arguments passed to boot loader */ while(Argument != NULL) { /* Check all provided parameters */ if(RtlWideStringCompare(Argument, L"DEFAULT=", 8) == 0) { /* Skip to the argument value and calculate argument length */ Argument += 8; Length = RtlWideStringLength(Argument, 0); /* Save default OS parameter in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Default); RtlCopyMemory(BlpConfiguration.Default, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Default[Length] = '\0'; } else if(RtlWideStringCompare(Argument, L"DEBUG=", 6) == 0) { /* Skip to the argument value */ Argument += 6; Length = RtlWideStringLength(Argument, 0); /* Save debug port in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Debug); RtlCopyMemory(BlpConfiguration.Debug, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Debug[Length] = '\0'; } else if(RtlWideStringCompare(Argument, L"SHELL", 5) == 0) { /* Force shell mode */ BlpConfiguration.Shell = TRUE; } else if(RtlWideStringCompare(Argument, L"THEME=", 6) == 0) { /* Skip to the argument value */ Argument += 6; Length = RtlWideStringLength(Argument, 0); /* Save theme in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Theme); RtlCopyMemory(BlpConfiguration.Theme, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Theme[Length] = '\0'; } else if(RtlWideStringCompare(Argument, L"TIMEOUT=", 8) == 0) { /* Skip to the argument value */ Argument += 8; /* Zero the timeout */ BlpConfiguration.Timeout = 0; /* Read the timeout value and store it in global configuration */ while(*Argument >= '0' && *Argument <= '9') { BlpConfiguration.Timeout *= 10; BlpConfiguration.Timeout += *Argument - '0'; Argument++; } } else if(RtlWideStringCompare(Argument, L"TUNE=", 5) == 0) { /* Skip to the argument value */ Argument += 5; Length = RtlWideStringLength(Argument, 0); /* Save theme in global configuration */ BlMemoryAllocatePool(Length, (PVOID *)&BlpConfiguration.Tune); RtlCopyMemory(BlpConfiguration.Tune, Argument, (Length * sizeof(WCHAR)) - 1); BlpConfiguration.Tune[Length] = '\0'; } /* Take next argument */ Argument = RtlWideStringTokenize(NULL, L" ", &LastArg); } }