diff --git a/boot/xtldr/includes/libxtos.hh b/boot/xtldr/includes/libxtos.hh index ba67c7c..fca9111 100644 --- a/boot/xtldr/includes/libxtos.hh +++ b/boot/xtldr/includes/libxtos.hh @@ -105,9 +105,9 @@ namespace RTL class String { public: - STATIC XTAPI SIZE_T CompareString(IN PCSTR String1, - IN PCSTR String2, - IN SIZE_T Length); + STATIC XTAPI LONG CompareString(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length); STATIC XTAPI SIZE_T StringLength(IN PCSTR String, IN SIZE_T MaxLength); STATIC XTAPI SIZE_T StringToWideString(OUT PWCHAR Destination, @@ -119,12 +119,12 @@ namespace RTL class WideString { public: - STATIC XTAPI SIZE_T CompareWideString(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length); - STATIC XTAPI SIZE_T CompareWideStringInsensitive(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length); + STATIC XTAPI LONG CompareWideString(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length); + STATIC XTAPI LONG CompareWideStringInsensitive(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length); STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count); diff --git a/boot/xtldr/includes/xtldr.hh b/boot/xtldr/includes/xtldr.hh index 8534bf1..8e54c8e 100644 --- a/boot/xtldr/includes/xtldr.hh +++ b/boot/xtldr/includes/xtldr.hh @@ -261,6 +261,7 @@ class Shell STATIC LIST_ENTRY ShellCommands; public: + STATIC XTCDECL VOID InitializeShell(); STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command, IN PCWSTR Description, IN PBL_SHELL_COMMAND Handler); diff --git a/boot/xtldr/modules/beep/beep.cc b/boot/xtldr/modules/beep/beep.cc index d1e548b..de05013 100644 --- a/boot/xtldr/modules/beep/beep.cc +++ b/boot/xtldr/modules/beep/beep.cc @@ -13,8 +13,78 @@ MODULE_AUTHOR(L"Rafal Kupiec "); MODULE_DESCRIPTION(L"Plays a GRUB compatible tune via PC speaker"); MODULE_LICENSE(L"GPLv3"); -MODULE_VERSION(L"0.1"); +MODULE_VERSION(L"0.2"); +/** + * Executes the beep shell command to play a musical tune. + * + * @param Argc + * Supplies the number of arguments passed to the command line. + * + * @param Argv + * Supplies a pointer to an array of null-terminated argument strings. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Beep::CommandBeep(IN ULONG Argc, + IN PWCHAR *Argv) +{ + WCHAR Tune[XTBL_SH_MAX_LINE_LENGTH]; + ULONG ArgumentIndex, TuneLength; + PWCHAR Character; + + /* Check the number of arguments */ + if(Argc < 2) + { + /* Invalid number of arguments, print usage message and return */ + XtLdrProtocol->Console.Print(L"Usage: beep [pitch2 duration2 ...]\n"); + return; + } + + /* Rebuild the space-separated argument string */ + TuneLength = 0; + for(ArgumentIndex = 1; ArgumentIndex < Argc; ArgumentIndex++) + { + /* Retrieve the pointer to the current argument string */ + Character = Argv[ArgumentIndex]; + while(*Character != L'\0') + { + /* Verify that the tune buffer has sufficient capacity */ + if(TuneLength >= XTBL_SH_MAX_LINE_LENGTH - 1) + { + /* Buffer capacity exceeded, print error message and return */ + XtLdrProtocol->Console.Print(L"ERROR: Tune is too long.\n"); + return; + } + + /* Copy the current character to the buffer and advance the source pointer */ + Tune[TuneLength++] = *Character++; + } + + /* Check if there are subsequent arguments */ + if(ArgumentIndex + 1 < Argc) + { + /* Verify that the tune buffer has sufficient capacity */ + if(TuneLength >= XTBL_SH_MAX_LINE_LENGTH - 1) + { + /* Buffer capacity exceeded, print error message and return */ + XtLdrProtocol->Console.Print(L"ERROR: Tune is too long.\n"); + return; + } + + /* Append a space character to the tune buffer */ + Tune[TuneLength++] = L' '; + } + } + + /* Terminate the reconstructed string and dispatch it to the playback routine */ + Tune[TuneLength] = L'\0'; + PlayTune(Tune); +} /** * Disables the PC speaker. @@ -102,6 +172,9 @@ Beep::InitializeModule(IN EFI_HANDLE ImageHandle, return STATUS_EFI_PROTOCOL_ERROR; } + /* Register the `beep` command */ + XtLdrProtocol->Shell.RegisterCommand(L"beep", L"Plays a GRUB compatible tune", CommandBeep); + /* Play the tune set in the configuration */ XtLdrProtocol->Config.GetValue(L"TUNE", &Tune); PlayTune(Tune); diff --git a/boot/xtldr/modules/beep/includes/beep.hh b/boot/xtldr/modules/beep/includes/beep.hh index 9b613d1..9936800 100644 --- a/boot/xtldr/modules/beep/includes/beep.hh +++ b/boot/xtldr/modules/beep/includes/beep.hh @@ -21,11 +21,12 @@ class Beep public: STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable); - STATIC XTCDECL VOID PlayTune(IN PWCHAR Arguments); private: + STATIC XTCDECL VOID CommandBeep(IN ULONG Argc, IN PWCHAR *Argv); STATIC XTCDECL VOID DisableToneBeep(); STATIC XTCDECL VOID EnableToneBeep(IN UINT Pitch); + STATIC XTCDECL VOID PlayTune(IN PWCHAR Arguments); STATIC XTCDECL UINT WideStringToNumber(IN PWCHAR String); }; diff --git a/boot/xtldr/shell.cc b/boot/xtldr/shell.cc index 88d1a07..ad918ac 100644 --- a/boot/xtldr/shell.cc +++ b/boot/xtldr/shell.cc @@ -307,6 +307,24 @@ Shell::ExecuteCommand(IN ULONG Argc, Console::Print(L"ERROR: '%S' is not recognized as a valid command.\n", Argv[0]); } +/** + * Initializes the bootloader shell. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Shell::InitializeShell() +{ + /* Initialize the shell commands list */ + RTL::LinkedList::InitializeListHead(&ShellCommands); + + /* Register all built-in commands */ + RegisterBuiltinCommands(); +} + /** * Splits the supplied raw command line string into an argument count and an argument vector suitable * for command dispatch. The input string is tokenized by whitespace. @@ -881,12 +899,6 @@ Shell::StartLoaderShell() /* Initialize console */ Console::InitializeConsole(); - /* Initialize the shell commands list */ - RTL::LinkedList::InitializeListHead(&ShellCommands); - - /* Register all built-in commands */ - RegisterBuiltinCommands(); - /* Clear the shell exit request flag */ ExitRequest = FALSE; diff --git a/boot/xtldr/volume.cc b/boot/xtldr/volume.cc index a2867b7..2292247 100644 --- a/boot/xtldr/volume.cc +++ b/boot/xtldr/volume.cc @@ -456,7 +456,7 @@ Volume::GetDevicePath(IN PWCHAR SystemPath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse system path */ - Debug::Print(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status); + Debug::Print(L"ERROR: Failed to parse system path: '%S' (Status Code: 0x%zX)\n", SystemPath, Status); return Status; } @@ -842,26 +842,26 @@ Volume::DissectArcPath(IN PWCHAR SystemPath, *PartNumber = 0; /* Look for the ARC path */ - if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0) + if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 10) == 0) { /* This is RAM disk */ ArcLength = 10; *DriveType = XTBL_BOOT_DEVICE_RAMDISK; } - else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 14) == 0) { /* This is ESP */ ArcLength = 14; *DriveType = XTBL_BOOT_DEVICE_ESP; } - else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 15) == 0) { /* This is a multi-disk port */ ArcLength = 15; ArcPath = SystemPath + ArcLength; /* Check for disk type */ - if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0) + if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"cdrom(", 6) == 0) { /* This is an optical drive */ ArcLength += 6; @@ -882,7 +882,7 @@ Volume::DissectArcPath(IN PWCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_CDROM; ArcLength++; } - else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"fdisk(", 6) == 0) { /* This is a floppy drive */ ArcLength += 6; @@ -903,7 +903,7 @@ Volume::DissectArcPath(IN PWCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_FLOPPY; ArcLength++; } - else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"rdisk(", 6) == 0) { /* This is a hard disk */ ArcLength += 6; @@ -926,7 +926,7 @@ Volume::DissectArcPath(IN PWCHAR SystemPath, ArcPath = SystemPath + ArcLength; /* Look for a partition */ - if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) + if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"partition(", 10) == 0) { /* Partition information found */ ArcLength += 10; diff --git a/boot/xtldr/xtldr.cc b/boot/xtldr/xtldr.cc index 3e0cac9..2fa8ab6 100644 --- a/boot/xtldr/xtldr.cc +++ b/boot/xtldr/xtldr.cc @@ -138,6 +138,9 @@ XtLoader::InitializeBootLoader(IN EFI_HANDLE ImageHandle, /* Initialize XTLDR configuration */ Configuration::InitializeConfiguration(); + /* Initialize shell */ + Shell::InitializeShell(); + /* Store SecureBoot status */ LoaderStatus.SecureBoot = EfiUtils::GetSecureBootStatus(); @@ -245,7 +248,7 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, for(;;); } - /* Initialize XTLDR and */ + /* Initialize XTLDR */ XtLoader::InitializeBootLoader(ImageHandle, SystemTable); /* Parse configuration options passed from UEFI shell */ diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 2d8ad5b..bed3d38 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -83,7 +83,7 @@ typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (XTCDECL *PBL_CONSOLE_WRITE)(IN PCWSTR String); typedef SIZE_T (XTAPI *PBL_COMPARE_MEMORY)(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length); -typedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); +typedef LONG (XTAPI *PBL_WIDESTRING_COMPARE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); typedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); typedef VOID (XTCDECL *PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...); typedef EFI_STATUS (XTCDECL *PBL_ENTER_FIRMWARE_SETUP)(); @@ -129,7 +129,7 @@ typedef EFI_STATUS (XTCDECL *PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN PC typedef EFI_STATUS (XTCDECL *PBL_REGISTER_BOOT_PROTOCOL)(IN PCWSTR SystemType, IN PEFI_GUID BootProtocolGuid); typedef VOID (XTCDECL *PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef EFI_STATUS (XTCDECL *PBL_SET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, IN PVOID VariableValue, IN UINT_PTR Size); -typedef SIZE_T (XTAPI *PBL_STRING_COMPARE)(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); +typedef LONG (XTAPI *PBL_STRING_COMPARE)(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); typedef SIZE_T (XTAPI *PBL_STRING_LENGTH)(IN PCSTR String, IN SIZE_T MaxLength); typedef SIZE_T (XTAPI *PBL_STRING_TO_WIDESTRING)(OUT PWCHAR Destination, IN PCSTR *Source, IN SIZE_T Length); typedef PCHAR (XTAPI *PBL_STRING_TRIM)(IN PCHAR String); @@ -141,7 +141,7 @@ typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INFO_DIALOG)(IN PCWSTR Caption, IN PCWSTR typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN OUT PWCHAR *InputFieldText); typedef XTBL_DIALOG_HANDLE (XTCDECL *PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN UCHAR Percentage); typedef VOID (XTCDECL *PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PCWSTR Message, IN UCHAR Percentage); -typedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE_INSENSITIVE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); +typedef LONG (XTAPI *PBL_WIDESTRING_COMPARE_INSENSITIVE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); typedef PWCHAR (XTAPI *PBL_WIDESTRING_CONCATENATE)(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count); typedef XTSTATUS (XTAPI *PBL_WIDESTRING_FORMAT)(IN PRTL_PRINT_CONTEXT Context, IN PCWSTR Format, IN VA_LIST ArgumentList); typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength); diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index ccdf179..7999ad2 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -59,28 +59,28 @@ RtlCompareMemory(IN PCVOID LeftBuffer, XTCLINK XTAPI -SIZE_T +LONG RtlCompareString(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); XTCLINK XTAPI -SIZE_T +LONG RtlCompareStringInsensitive(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); XTCLINK XTAPI -SIZE_T +LONG RtlCompareWideString(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); XTCLINK XTAPI -SIZE_T +LONG RtlCompareWideStringInsensitive(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); diff --git a/xtoskrnl/includes/rtl/string.hh b/xtoskrnl/includes/rtl/string.hh index f6feec4..d06ca07 100644 --- a/xtoskrnl/includes/rtl/string.hh +++ b/xtoskrnl/includes/rtl/string.hh @@ -18,12 +18,12 @@ namespace RTL class String { public: - STATIC XTAPI SIZE_T CompareString(IN PCSTR String1, - IN PCSTR String2, - IN SIZE_T Length); - STATIC XTAPI SIZE_T CompareStringInsensitive(IN PCSTR String1, - IN PCSTR String2, - IN SIZE_T Length); + STATIC XTAPI LONG CompareString(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length); + STATIC XTAPI LONG CompareStringInsensitive(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length); STATIC XTAPI PCHAR ConcatenateString(OUT PCHAR Destination, IN PCHAR Source, IN SIZE_T Count); diff --git a/xtoskrnl/includes/rtl/widestr.hh b/xtoskrnl/includes/rtl/widestr.hh index 8b4b459..a091280 100644 --- a/xtoskrnl/includes/rtl/widestr.hh +++ b/xtoskrnl/includes/rtl/widestr.hh @@ -18,12 +18,12 @@ namespace RTL class WideString { public: - STATIC XTAPI SIZE_T CompareWideString(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length); - STATIC XTAPI SIZE_T CompareWideStringInsensitive(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length); + STATIC XTAPI LONG CompareWideString(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length); + STATIC XTAPI LONG CompareWideStringInsensitive(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length); STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count); diff --git a/xtoskrnl/rtl/exports.cc b/xtoskrnl/rtl/exports.cc index a7d40cb..ec7c0da 100644 --- a/xtoskrnl/rtl/exports.cc +++ b/xtoskrnl/rtl/exports.cc @@ -166,7 +166,7 @@ RtlCompareMemory(IN PCVOID LeftBuffer, */ XTCLINK XTAPI -SIZE_T +LONG RtlCompareString(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length) @@ -192,7 +192,7 @@ RtlCompareString(IN PCSTR String1, */ XTCLINK XTAPI -SIZE_T +LONG RtlCompareStringInsensitive(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length) @@ -218,7 +218,7 @@ RtlCompareStringInsensitive(IN PCSTR String1, */ XTCLINK XTAPI -SIZE_T +LONG RtlCompareWideString(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length) @@ -244,7 +244,7 @@ RtlCompareWideString(IN PCWSTR String1, */ XTCLINK XTAPI -SIZE_T +LONG RtlCompareWideStringInsensitive(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length) diff --git a/xtoskrnl/rtl/string.cc b/xtoskrnl/rtl/string.cc index 12b5182..5fbf467 100644 --- a/xtoskrnl/rtl/string.cc +++ b/xtoskrnl/rtl/string.cc @@ -26,7 +26,7 @@ * @since XT 1.0 */ XTAPI -SIZE_T +LONG RTL::String::CompareString(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length) @@ -78,7 +78,7 @@ RTL::String::CompareString(IN PCSTR String1, * @since XT 1.0 */ XTAPI -SIZE_T +LONG RTL::String::CompareStringInsensitive(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length) @@ -124,6 +124,13 @@ RTL::String::CompareStringInsensitive(IN PCSTR String1, Index++; } + /* Check if one string ended before the other */ + if((Length == 0 || Index < Length) && (String1[Index] != String2[Index])) + { + /* Strings are not equal */ + return String1[Index] > String2[Index] ? 1 : -1; + } + /* Strings are equal */ return 0; } diff --git a/xtoskrnl/rtl/widestr.cc b/xtoskrnl/rtl/widestr.cc index aed6c05..63a64f1 100644 --- a/xtoskrnl/rtl/widestr.cc +++ b/xtoskrnl/rtl/widestr.cc @@ -26,7 +26,7 @@ * @since XT 1.0 */ XTAPI -SIZE_T +LONG RTL::WideString::CompareWideString(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length) @@ -78,7 +78,7 @@ RTL::WideString::CompareWideString(IN PCWSTR String1, * @since XT 1.0 */ XTAPI -SIZE_T +LONG RTL::WideString::CompareWideStringInsensitive(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length) @@ -124,6 +124,13 @@ RTL::WideString::CompareWideStringInsensitive(IN PCWSTR String1, Index++; } + /* Check if one wide string ended before the other */ + if((Length == 0 || Index < Length) && (String1[Index] != String2[Index])) + { + /* Wide strings are not equal */ + return String1[Index] > String2[Index] ? 1 : -1; + } + /* Strings are equal */ return 0; }