4 #include "efishellintf.h"
5 #include "efishellparm.h"
7 #ifndef MAX_ARGV_CONTENTS_SIZE
8 # define MAX_CMDLINE_SIZE 1024
11 # define MAX_CMDLINE_ARGC 32
15 Parse LoadedImage options area, called only in case the regular
16 shell protos are not available.
18 Format of LoadedImage->LoadOptions appears to be a
19 single-space-separated list of args (looks like the shell already
20 pre-parses the input, it apparently folds several consecutive spaces
22 argv[0] space argv[1] (etc.) argv[N] space \0 cwd \0 other data
23 For safety, we support the trailing \0 without a space before, as
24 well as several consecutive spaces (-> several args).
28 GetShellArgcArgvFromLoadedImage(
29 EFI_HANDLE ImageHandle
,
34 void *LoadedImage
= NULL
;
35 static CHAR16 ArgvContents
[MAX_CMDLINE_SIZE
];
36 static CHAR16
*Argv
[MAX_CMDLINE_ARGC
], *ArgStart
, *c
;
37 UINTN Argc
= 0, BufLen
;
39 Status
= uefi_call_wrapper(BS
->OpenProtocol
, 6,
45 EFI_OPEN_PROTOCOL_GET_PROTOCOL
47 if (EFI_ERROR(Status
))
50 BufLen
= ((EFI_LOADED_IMAGE
*)LoadedImage
)->LoadOptionsSize
;
51 if (BufLen
< 2) /* We are expecting at least a \0 */
53 else if (BufLen
> sizeof(ArgvContents
))
54 BufLen
= sizeof(ArgvContents
);
56 CopyMem(ArgvContents
, ((EFI_LOADED_IMAGE
*)LoadedImage
)->LoadOptions
, BufLen
);
57 ArgvContents
[MAX_CMDLINE_SIZE
- 1] = L
'\0';
59 for (c
= ArgStart
= ArgvContents
; *c
!= L
'\0' ; ++c
) {
62 if (Argc
< MAX_CMDLINE_ARGC
) Argv
[Argc
++] = ArgStart
;
67 if ((*ArgStart
!= L
'\0') && (Argc
< MAX_CMDLINE_ARGC
))
68 Argv
[Argc
++] = ArgStart
;
70 // Print(L"Got argc/argv from loaded image proto\n");
75 INTN
GetShellArgcArgv(EFI_HANDLE ImageHandle
, CHAR16
**Argv
[])
77 // Code inspired from EDK2's
78 // ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c (BSD)
80 static const EFI_GUID EfiShellParametersProtocolGuid
81 = EFI_SHELL_PARAMETERS_PROTOCOL_GUID
;
82 static const EFI_GUID ShellInterfaceProtocolGuid
83 = SHELL_INTERFACE_PROTOCOL_GUID
;
84 EFI_SHELL_PARAMETERS_PROTOCOL
*EfiShellParametersProtocol
= NULL
;
85 EFI_SHELL_INTERFACE
*EfiShellInterfaceProtocol
= NULL
;
87 Status
= uefi_call_wrapper(BS
->OpenProtocol
, 6,
89 (EFI_GUID
*)&EfiShellParametersProtocolGuid
,
90 (VOID
**)&EfiShellParametersProtocol
,
93 EFI_OPEN_PROTOCOL_GET_PROTOCOL
95 if (!EFI_ERROR(Status
))
97 // use shell 2.0 interface
98 // Print(L"Got argc/argv from shell intf proto\n");
99 *Argv
= EfiShellParametersProtocol
->Argv
;
100 return EfiShellParametersProtocol
->Argc
;
103 // try to get shell 1.0 interface instead.
104 Status
= uefi_call_wrapper(BS
->OpenProtocol
, 6,
106 (EFI_GUID
*)&ShellInterfaceProtocolGuid
,
107 (VOID
**)&EfiShellInterfaceProtocol
,
110 EFI_OPEN_PROTOCOL_GET_PROTOCOL
112 if (!EFI_ERROR(Status
))
114 // Print(L"Got argc/argv from shell params proto\n");
115 *Argv
= EfiShellInterfaceProtocol
->Argv
;
116 return EfiShellInterfaceProtocol
->Argc
;
119 // shell 1.0 and 2.0 interfaces failed
120 return GetShellArgcArgvFromLoadedImage(ImageHandle
, Argv
);