cmdline.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "lib.h"
  2. #ifndef MAX_ARGV_CONTENTS_SIZE
  3. # define MAX_CMDLINE_SIZE 1024
  4. #endif
  5. #ifndef MAX_ARGC
  6. # define MAX_CMDLINE_ARGC 32
  7. #endif
  8. /*
  9. Parse LoadedImage options area, called only in case the regular
  10. shell protos are not available.
  11. Format of LoadedImage->LoadOptions appears to be a
  12. single-space-separated list of args (looks like the shell already
  13. pre-parses the input, it apparently folds several consecutive spaces
  14. into one):
  15. argv[0] space argv[1] (etc.) argv[N] space \0 cwd \0 other data
  16. For safety, we support the trailing \0 without a space before, as
  17. well as several consecutive spaces (-> several args).
  18. */
  19. INTN
  20. GetShellArgcArgv(
  21. EFI_HANDLE ImageHandle,
  22. CHAR16 **ResultArgv[]
  23. )
  24. {
  25. EFI_STATUS Status;
  26. EFI_LOADED_IMAGE *LoadedImage = NULL;
  27. static CHAR16 ArgvContents[MAX_CMDLINE_SIZE];
  28. static CHAR16 *Argv[MAX_CMDLINE_ARGC], *ArgStart, *c;
  29. UINTN Argc = 0, BufLen;
  30. Status = uefi_call_wrapper(BS->OpenProtocol, 6,
  31. ImageHandle,
  32. &LoadedImageProtocol,
  33. &LoadedImage,
  34. ImageHandle,
  35. NULL,
  36. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  37. );
  38. if (EFI_ERROR(Status))
  39. return -1;
  40. BufLen = LoadedImage->LoadOptionsSize;
  41. if (BufLen < 2) /* We are expecting at least a \0 */
  42. return -1;
  43. else if (BufLen > sizeof(ArgvContents))
  44. BufLen = sizeof(ArgvContents);
  45. CopyMem(ArgvContents, LoadedImage->LoadOptions, BufLen);
  46. ArgvContents[MAX_CMDLINE_SIZE - 1] = L'\0';
  47. for (c = ArgStart = ArgvContents ; *c != L'\0' ; ++c) {
  48. if (*c == L' ') {
  49. *c = L'\0';
  50. if (Argc < MAX_CMDLINE_ARGC) Argv[Argc++] = ArgStart;
  51. ArgStart = c + 1;
  52. }
  53. }
  54. if ((*ArgStart != L'\0') && (Argc < MAX_CMDLINE_ARGC))
  55. Argv[Argc++] = ArgStart;
  56. *ResultArgv = Argv;
  57. return Argc;
  58. }