From 328b785b187c3f977f740fb0cf84206fe551e2e1 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 1 Aug 2026 11:40:00 +0200 Subject: [PATCH] Add beep shell command --- boot/xtldr/modules/beep/beep.cc | 75 +++++++++++++++++++++++- boot/xtldr/modules/beep/includes/beep.hh | 3 +- 2 files changed, 76 insertions(+), 2 deletions(-) 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); };