cmdline.c revision 1.1.1.1.2.2 1 1.1.1.1.2.2 pgoyette /* $NetBSD: cmdline.c,v 1.1.1.1.2.2 2018/09/06 06:56:39 pgoyette Exp $ */
2 1.1.1.1.2.2 pgoyette
3 1.1.1.1.2.2 pgoyette #include "lib.h"
4 1.1.1.1.2.2 pgoyette
5 1.1.1.1.2.2 pgoyette #include "efiprot.h"
6 1.1.1.1.2.2 pgoyette #include "efishellintf.h"
7 1.1.1.1.2.2 pgoyette #include "efishellparm.h"
8 1.1.1.1.2.2 pgoyette
9 1.1.1.1.2.2 pgoyette #ifndef MAX_ARGV_CONTENTS_SIZE
10 1.1.1.1.2.2 pgoyette # define MAX_CMDLINE_SIZE 1024
11 1.1.1.1.2.2 pgoyette #endif
12 1.1.1.1.2.2 pgoyette #ifndef MAX_ARGC
13 1.1.1.1.2.2 pgoyette # define MAX_CMDLINE_ARGC 32
14 1.1.1.1.2.2 pgoyette #endif
15 1.1.1.1.2.2 pgoyette
16 1.1.1.1.2.2 pgoyette /*
17 1.1.1.1.2.2 pgoyette Parse LoadedImage options area, called only in case the regular
18 1.1.1.1.2.2 pgoyette shell protos are not available.
19 1.1.1.1.2.2 pgoyette
20 1.1.1.1.2.2 pgoyette Format of LoadedImage->LoadOptions appears to be a
21 1.1.1.1.2.2 pgoyette single-space-separated list of args (looks like the shell already
22 1.1.1.1.2.2 pgoyette pre-parses the input, it apparently folds several consecutive spaces
23 1.1.1.1.2.2 pgoyette into one):
24 1.1.1.1.2.2 pgoyette argv[0] space argv[1] (etc.) argv[N] space \0 cwd \0 other data
25 1.1.1.1.2.2 pgoyette For safety, we support the trailing \0 without a space before, as
26 1.1.1.1.2.2 pgoyette well as several consecutive spaces (-> several args).
27 1.1.1.1.2.2 pgoyette */
28 1.1.1.1.2.2 pgoyette static
29 1.1.1.1.2.2 pgoyette INTN
30 1.1.1.1.2.2 pgoyette GetShellArgcArgvFromLoadedImage(
31 1.1.1.1.2.2 pgoyette EFI_HANDLE ImageHandle,
32 1.1.1.1.2.2 pgoyette CHAR16 **ResultArgv[]
33 1.1.1.1.2.2 pgoyette )
34 1.1.1.1.2.2 pgoyette {
35 1.1.1.1.2.2 pgoyette EFI_STATUS Status;
36 1.1.1.1.2.2 pgoyette void *LoadedImage = NULL;
37 1.1.1.1.2.2 pgoyette static CHAR16 ArgvContents[MAX_CMDLINE_SIZE];
38 1.1.1.1.2.2 pgoyette static CHAR16 *Argv[MAX_CMDLINE_ARGC], *ArgStart, *c;
39 1.1.1.1.2.2 pgoyette UINTN Argc = 0, BufLen;
40 1.1.1.1.2.2 pgoyette
41 1.1.1.1.2.2 pgoyette Status = uefi_call_wrapper(BS->OpenProtocol, 6,
42 1.1.1.1.2.2 pgoyette ImageHandle,
43 1.1.1.1.2.2 pgoyette &LoadedImageProtocol,
44 1.1.1.1.2.2 pgoyette &LoadedImage,
45 1.1.1.1.2.2 pgoyette ImageHandle,
46 1.1.1.1.2.2 pgoyette NULL,
47 1.1.1.1.2.2 pgoyette EFI_OPEN_PROTOCOL_GET_PROTOCOL
48 1.1.1.1.2.2 pgoyette );
49 1.1.1.1.2.2 pgoyette if (EFI_ERROR(Status))
50 1.1.1.1.2.2 pgoyette return -1;
51 1.1.1.1.2.2 pgoyette
52 1.1.1.1.2.2 pgoyette BufLen = ((EFI_LOADED_IMAGE *)LoadedImage)->LoadOptionsSize;
53 1.1.1.1.2.2 pgoyette if (BufLen < 2) /* We are expecting at least a \0 */
54 1.1.1.1.2.2 pgoyette return -1;
55 1.1.1.1.2.2 pgoyette else if (BufLen > sizeof(ArgvContents))
56 1.1.1.1.2.2 pgoyette BufLen = sizeof(ArgvContents);
57 1.1.1.1.2.2 pgoyette
58 1.1.1.1.2.2 pgoyette CopyMem(ArgvContents, ((EFI_LOADED_IMAGE *)LoadedImage)->LoadOptions, BufLen);
59 1.1.1.1.2.2 pgoyette ArgvContents[MAX_CMDLINE_SIZE - 1] = L'\0';
60 1.1.1.1.2.2 pgoyette
61 1.1.1.1.2.2 pgoyette for (c = ArgStart = ArgvContents ; *c != L'\0' ; ++c) {
62 1.1.1.1.2.2 pgoyette if (*c == L' ') {
63 1.1.1.1.2.2 pgoyette *c = L'\0';
64 1.1.1.1.2.2 pgoyette if (Argc < MAX_CMDLINE_ARGC) Argv[Argc++] = ArgStart;
65 1.1.1.1.2.2 pgoyette ArgStart = c + 1;
66 1.1.1.1.2.2 pgoyette }
67 1.1.1.1.2.2 pgoyette }
68 1.1.1.1.2.2 pgoyette
69 1.1.1.1.2.2 pgoyette if ((*ArgStart != L'\0') && (Argc < MAX_CMDLINE_ARGC))
70 1.1.1.1.2.2 pgoyette Argv[Argc++] = ArgStart;
71 1.1.1.1.2.2 pgoyette
72 1.1.1.1.2.2 pgoyette // Print(L"Got argc/argv from loaded image proto\n");
73 1.1.1.1.2.2 pgoyette *ResultArgv = Argv;
74 1.1.1.1.2.2 pgoyette return Argc;
75 1.1.1.1.2.2 pgoyette }
76 1.1.1.1.2.2 pgoyette
77 1.1.1.1.2.2 pgoyette INTN GetShellArgcArgv(EFI_HANDLE ImageHandle, CHAR16 **Argv[])
78 1.1.1.1.2.2 pgoyette {
79 1.1.1.1.2.2 pgoyette // Code inspired from EDK2's
80 1.1.1.1.2.2 pgoyette // ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.c (BSD)
81 1.1.1.1.2.2 pgoyette EFI_STATUS Status;
82 1.1.1.1.2.2 pgoyette static const EFI_GUID EfiShellParametersProtocolGuid
83 1.1.1.1.2.2 pgoyette = EFI_SHELL_PARAMETERS_PROTOCOL_GUID;
84 1.1.1.1.2.2 pgoyette static const EFI_GUID ShellInterfaceProtocolGuid
85 1.1.1.1.2.2 pgoyette = SHELL_INTERFACE_PROTOCOL_GUID;
86 1.1.1.1.2.2 pgoyette EFI_SHELL_PARAMETERS_PROTOCOL *EfiShellParametersProtocol = NULL;
87 1.1.1.1.2.2 pgoyette EFI_SHELL_INTERFACE *EfiShellInterfaceProtocol = NULL;
88 1.1.1.1.2.2 pgoyette
89 1.1.1.1.2.2 pgoyette Status = uefi_call_wrapper(BS->OpenProtocol, 6,
90 1.1.1.1.2.2 pgoyette ImageHandle,
91 1.1.1.1.2.2 pgoyette (EFI_GUID*)&EfiShellParametersProtocolGuid,
92 1.1.1.1.2.2 pgoyette (VOID **)&EfiShellParametersProtocol,
93 1.1.1.1.2.2 pgoyette ImageHandle,
94 1.1.1.1.2.2 pgoyette NULL,
95 1.1.1.1.2.2 pgoyette EFI_OPEN_PROTOCOL_GET_PROTOCOL
96 1.1.1.1.2.2 pgoyette );
97 1.1.1.1.2.2 pgoyette if (!EFI_ERROR(Status))
98 1.1.1.1.2.2 pgoyette {
99 1.1.1.1.2.2 pgoyette // use shell 2.0 interface
100 1.1.1.1.2.2 pgoyette // Print(L"Got argc/argv from shell intf proto\n");
101 1.1.1.1.2.2 pgoyette *Argv = EfiShellParametersProtocol->Argv;
102 1.1.1.1.2.2 pgoyette return EfiShellParametersProtocol->Argc;
103 1.1.1.1.2.2 pgoyette }
104 1.1.1.1.2.2 pgoyette
105 1.1.1.1.2.2 pgoyette // try to get shell 1.0 interface instead.
106 1.1.1.1.2.2 pgoyette Status = uefi_call_wrapper(BS->OpenProtocol, 6,
107 1.1.1.1.2.2 pgoyette ImageHandle,
108 1.1.1.1.2.2 pgoyette (EFI_GUID*)&ShellInterfaceProtocolGuid,
109 1.1.1.1.2.2 pgoyette (VOID **)&EfiShellInterfaceProtocol,
110 1.1.1.1.2.2 pgoyette ImageHandle,
111 1.1.1.1.2.2 pgoyette NULL,
112 1.1.1.1.2.2 pgoyette EFI_OPEN_PROTOCOL_GET_PROTOCOL
113 1.1.1.1.2.2 pgoyette );
114 1.1.1.1.2.2 pgoyette if (!EFI_ERROR(Status))
115 1.1.1.1.2.2 pgoyette {
116 1.1.1.1.2.2 pgoyette // Print(L"Got argc/argv from shell params proto\n");
117 1.1.1.1.2.2 pgoyette *Argv = EfiShellInterfaceProtocol->Argv;
118 1.1.1.1.2.2 pgoyette return EfiShellInterfaceProtocol->Argc;
119 1.1.1.1.2.2 pgoyette }
120 1.1.1.1.2.2 pgoyette
121 1.1.1.1.2.2 pgoyette // shell 1.0 and 2.0 interfaces failed
122 1.1.1.1.2.2 pgoyette return GetShellArgcArgvFromLoadedImage(ImageHandle, Argv);
123 1.1.1.1.2.2 pgoyette }
124