1 | /** @file
|
---|
2 | Helper functions for configuring or getting the parameters relating to HTTP Boot.
|
---|
3 |
|
---|
4 | Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
---|
5 | This program and the accompanying materials
|
---|
6 | are licensed and made available under the terms and conditions of the BSD License
|
---|
7 | which accompanies this distribution. The full text of the license may be found at
|
---|
8 | http://opensource.org/licenses/bsd-license.php
|
---|
9 |
|
---|
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
12 |
|
---|
13 | **/
|
---|
14 |
|
---|
15 | #include "HttpBootDxe.h"
|
---|
16 | #include <Library/UefiBootManagerLib.h>
|
---|
17 |
|
---|
18 | CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA";
|
---|
19 |
|
---|
20 | /**
|
---|
21 | Add new boot option for HTTP boot.
|
---|
22 |
|
---|
23 | @param[in] Private Pointer to the driver private data.
|
---|
24 | @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6.
|
---|
25 | @param[in] Description The description text of the boot option.
|
---|
26 | @param[in] Uri The URI string of the boot file.
|
---|
27 |
|
---|
28 | @retval EFI_SUCCESS The boot option is created successfully.
|
---|
29 | @retval Others Failed to create new boot option.
|
---|
30 |
|
---|
31 | **/
|
---|
32 | EFI_STATUS
|
---|
33 | HttpBootAddBootOption (
|
---|
34 | IN HTTP_BOOT_PRIVATE_DATA *Private,
|
---|
35 | IN BOOLEAN UsingIpv6,
|
---|
36 | IN CHAR16 *Description,
|
---|
37 | IN CHAR16 *Uri
|
---|
38 | )
|
---|
39 | {
|
---|
40 | EFI_DEV_PATH *Node;
|
---|
41 | EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
|
---|
42 | EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
---|
43 | UINTN Length;
|
---|
44 | CHAR8 AsciiUri[URI_STR_MAX_SIZE];
|
---|
45 | EFI_STATUS Status;
|
---|
46 | UINTN Index;
|
---|
47 | EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
|
---|
48 |
|
---|
49 | NewDevicePath = NULL;
|
---|
50 | Node = NULL;
|
---|
51 | TmpDevicePath = NULL;
|
---|
52 |
|
---|
53 | if (StrLen (Description) == 0) {
|
---|
54 | return EFI_INVALID_PARAMETER;
|
---|
55 | }
|
---|
56 |
|
---|
57 | //
|
---|
58 | // Convert the scheme to all lower case.
|
---|
59 | //
|
---|
60 | for (Index = 0; Index < StrLen (Uri); Index++) {
|
---|
61 | if (Uri[Index] == L':') {
|
---|
62 | break;
|
---|
63 | }
|
---|
64 | if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
|
---|
65 | Uri[Index] -= (CHAR16)(L'A' - L'a');
|
---|
66 | }
|
---|
67 | }
|
---|
68 |
|
---|
69 | //
|
---|
70 | // Only accept empty URI, or http and https URI.
|
---|
71 | //
|
---|
72 | if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) {
|
---|
73 | return EFI_INVALID_PARAMETER;
|
---|
74 | }
|
---|
75 |
|
---|
76 | //
|
---|
77 | // Create a new device path by appending the IP node and URI node to
|
---|
78 | // the driver's parent device path
|
---|
79 | //
|
---|
80 | if (!UsingIpv6) {
|
---|
81 | Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
|
---|
82 | if (Node == NULL) {
|
---|
83 | Status = EFI_OUT_OF_RESOURCES;
|
---|
84 | goto ON_EXIT;
|
---|
85 | }
|
---|
86 | Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
|
---|
87 | Node->Ipv4.Header.SubType = MSG_IPv4_DP;
|
---|
88 | SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
|
---|
89 | } else {
|
---|
90 | Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
|
---|
91 | if (Node == NULL) {
|
---|
92 | Status = EFI_OUT_OF_RESOURCES;
|
---|
93 | goto ON_EXIT;
|
---|
94 | }
|
---|
95 | Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
|
---|
96 | Node->Ipv6.Header.SubType = MSG_IPv6_DP;
|
---|
97 | SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
|
---|
98 | }
|
---|
99 | TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
|
---|
100 | FreePool (Node);
|
---|
101 | if (TmpDevicePath == NULL) {
|
---|
102 | return EFI_OUT_OF_RESOURCES;
|
---|
103 | }
|
---|
104 | //
|
---|
105 | // Update the URI node with the input boot file URI.
|
---|
106 | //
|
---|
107 | UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri));
|
---|
108 | Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
|
---|
109 | Node = AllocatePool (Length);
|
---|
110 | if (Node == NULL) {
|
---|
111 | Status = EFI_OUT_OF_RESOURCES;
|
---|
112 | FreePool (TmpDevicePath);
|
---|
113 | goto ON_EXIT;
|
---|
114 | }
|
---|
115 | Node->DevPath.Type = MESSAGING_DEVICE_PATH;
|
---|
116 | Node->DevPath.SubType = MSG_URI_DP;
|
---|
117 | SetDevicePathNodeLength (Node, Length);
|
---|
118 | CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
|
---|
119 | NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
|
---|
120 | FreePool (Node);
|
---|
121 | FreePool (TmpDevicePath);
|
---|
122 | if (NewDevicePath == NULL) {
|
---|
123 | Status = EFI_OUT_OF_RESOURCES;
|
---|
124 | goto ON_EXIT;
|
---|
125 | }
|
---|
126 |
|
---|
127 | //
|
---|
128 | // Add a new load option.
|
---|
129 | //
|
---|
130 | Status = EfiBootManagerInitializeLoadOption (
|
---|
131 | &NewOption,
|
---|
132 | LoadOptionNumberUnassigned,
|
---|
133 | LoadOptionTypeBoot,
|
---|
134 | LOAD_OPTION_ACTIVE,
|
---|
135 | Description,
|
---|
136 | NewDevicePath,
|
---|
137 | NULL,
|
---|
138 | 0
|
---|
139 | );
|
---|
140 | if (EFI_ERROR (Status)) {
|
---|
141 | goto ON_EXIT;
|
---|
142 | }
|
---|
143 |
|
---|
144 | Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
|
---|
145 | EfiBootManagerFreeLoadOption (&NewOption);
|
---|
146 |
|
---|
147 | ON_EXIT:
|
---|
148 |
|
---|
149 | if (NewDevicePath != NULL) {
|
---|
150 | FreePool (NewDevicePath);
|
---|
151 | }
|
---|
152 |
|
---|
153 | return Status;
|
---|
154 | }
|
---|
155 |
|
---|
156 | /**
|
---|
157 |
|
---|
158 | This function allows the caller to request the current
|
---|
159 | configuration for one or more named elements. The resulting
|
---|
160 | string is in <ConfigAltResp> format. Also, any and all alternative
|
---|
161 | configuration strings shall be appended to the end of the
|
---|
162 | current configuration string. If they are, they must appear
|
---|
163 | after the current configuration. They must contain the same
|
---|
164 | routing (GUID, NAME, PATH) as the current configuration string.
|
---|
165 | They must have an additional description indicating the type of
|
---|
166 | alternative configuration the string represents,
|
---|
167 | "ALTCFG=<StringToken>". That <StringToken> (when
|
---|
168 | converted from Hex UNICODE to binary) is a reference to a
|
---|
169 | string in the associated string pack.
|
---|
170 |
|
---|
171 | @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
172 |
|
---|
173 | @param[in] Request A null-terminated Unicode string in
|
---|
174 | <ConfigRequest> format. Note that this
|
---|
175 | includes the routing information as well as
|
---|
176 | the configurable name / value pairs. It is
|
---|
177 | invalid for this string to be in
|
---|
178 | <MultiConfigRequest> format.
|
---|
179 |
|
---|
180 | @param[out] Progress On return, points to a character in the
|
---|
181 | Request string. Points to the string's null
|
---|
182 | terminator if request was successful. Points
|
---|
183 | to the most recent "&" before the first
|
---|
184 | failing name / value pair (or the beginning
|
---|
185 | of the string if the failure is in the first
|
---|
186 | name / value pair) if the request was not successful.
|
---|
187 |
|
---|
188 | @param[out] Results A null-terminated Unicode string in
|
---|
189 | <ConfigAltResp> format which has all values
|
---|
190 | filled in for the names in the Request string.
|
---|
191 | String to be allocated by the called function.
|
---|
192 |
|
---|
193 | @retval EFI_SUCCESS The Results string is filled with the
|
---|
194 | values corresponding to all requested
|
---|
195 | names.
|
---|
196 |
|
---|
197 | @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
|
---|
198 | parts of the results that must be
|
---|
199 | stored awaiting possible future
|
---|
200 | protocols.
|
---|
201 |
|
---|
202 | @retval EFI_INVALID_PARAMETER For example, passing in a NULL
|
---|
203 | for the Request parameter
|
---|
204 | would result in this type of
|
---|
205 | error. In this case, the
|
---|
206 | Progress parameter would be
|
---|
207 | set to NULL.
|
---|
208 |
|
---|
209 | @retval EFI_NOT_FOUND Routing data doesn't match any
|
---|
210 | known driver. Progress set to the
|
---|
211 | first character in the routing header.
|
---|
212 | Note: There is no requirement that the
|
---|
213 | driver validate the routing data. It
|
---|
214 | must skip the <ConfigHdr> in order to
|
---|
215 | process the names.
|
---|
216 |
|
---|
217 | @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
|
---|
218 | to most recent "&" before the
|
---|
219 | error or the beginning of the
|
---|
220 | string.
|
---|
221 |
|
---|
222 | @retval EFI_INVALID_PARAMETER Unknown name. Progress points
|
---|
223 | to the & before the name in
|
---|
224 | question.
|
---|
225 |
|
---|
226 | **/
|
---|
227 | EFI_STATUS
|
---|
228 | EFIAPI
|
---|
229 | HttpBootFormExtractConfig (
|
---|
230 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
231 | IN CONST EFI_STRING Request,
|
---|
232 | OUT EFI_STRING *Progress,
|
---|
233 | OUT EFI_STRING *Results
|
---|
234 | )
|
---|
235 | {
|
---|
236 | EFI_STATUS Status;
|
---|
237 | UINTN BufferSize;
|
---|
238 | HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
---|
239 | EFI_STRING ConfigRequestHdr;
|
---|
240 | EFI_STRING ConfigRequest;
|
---|
241 | BOOLEAN AllocatedRequest;
|
---|
242 | UINTN Size;
|
---|
243 |
|
---|
244 | if (Progress == NULL || Results == NULL) {
|
---|
245 | return EFI_INVALID_PARAMETER;
|
---|
246 | }
|
---|
247 |
|
---|
248 | *Progress = Request;
|
---|
249 | if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
|
---|
250 | return EFI_NOT_FOUND;
|
---|
251 | }
|
---|
252 |
|
---|
253 | ConfigRequestHdr = NULL;
|
---|
254 | ConfigRequest = NULL;
|
---|
255 | AllocatedRequest = FALSE;
|
---|
256 | Size = 0;
|
---|
257 |
|
---|
258 | CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
---|
259 | //
|
---|
260 | // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
---|
261 | //
|
---|
262 | BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
|
---|
263 | ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
|
---|
264 | StrCpyS (CallbackInfo->HttpBootNvData.Description, DESCRIPTION_STR_MAX_SIZE / sizeof (CHAR16), HTTP_BOOT_DEFAULT_DESCRIPTION_STR);
|
---|
265 |
|
---|
266 | ConfigRequest = Request;
|
---|
267 | if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
|
---|
268 | //
|
---|
269 | // Request has no request element, construct full request string.
|
---|
270 | // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
---|
271 | // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
---|
272 | //
|
---|
273 | ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);
|
---|
274 | Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
---|
275 | ConfigRequest = AllocateZeroPool (Size);
|
---|
276 | if (ConfigRequest == NULL) {
|
---|
277 | return EFI_OUT_OF_RESOURCES;
|
---|
278 | }
|
---|
279 | AllocatedRequest = TRUE;
|
---|
280 | UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
|
---|
281 | FreePool (ConfigRequestHdr);
|
---|
282 | }
|
---|
283 |
|
---|
284 | Status = gHiiConfigRouting->BlockToConfig (
|
---|
285 | gHiiConfigRouting,
|
---|
286 | ConfigRequest,
|
---|
287 | (UINT8 *) &CallbackInfo->HttpBootNvData,
|
---|
288 | BufferSize,
|
---|
289 | Results,
|
---|
290 | Progress
|
---|
291 | );
|
---|
292 |
|
---|
293 | //
|
---|
294 | // Free the allocated config request string.
|
---|
295 | //
|
---|
296 | if (AllocatedRequest) {
|
---|
297 | FreePool (ConfigRequest);
|
---|
298 | ConfigRequest = NULL;
|
---|
299 | }
|
---|
300 | //
|
---|
301 | // Set Progress string to the original request string.
|
---|
302 | //
|
---|
303 | if (Request == NULL) {
|
---|
304 | *Progress = NULL;
|
---|
305 | } else if (StrStr (Request, L"OFFSET") == NULL) {
|
---|
306 | *Progress = Request + StrLen (Request);
|
---|
307 | }
|
---|
308 |
|
---|
309 | return Status;
|
---|
310 | }
|
---|
311 |
|
---|
312 | /**
|
---|
313 |
|
---|
314 | This function applies changes in a driver's configuration.
|
---|
315 | Input is a Configuration, which has the routing data for this
|
---|
316 | driver followed by name / value configuration pairs. The driver
|
---|
317 | must apply those pairs to its configurable storage. If the
|
---|
318 | driver's configuration is stored in a linear block of data
|
---|
319 | and the driver's name / value pairs are in <BlockConfig>
|
---|
320 | format, it may use the ConfigToBlock helper function (above) to
|
---|
321 | simplify the job.
|
---|
322 |
|
---|
323 | @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
324 |
|
---|
325 | @param[in] Configuration A null-terminated Unicode string in
|
---|
326 | <ConfigString> format.
|
---|
327 |
|
---|
328 | @param[out] Progress A pointer to a string filled in with the
|
---|
329 | offset of the most recent '&' before the
|
---|
330 | first failing name / value pair (or the
|
---|
331 | beginning of the string if the failure
|
---|
332 | is in the first name / value pair) or
|
---|
333 | the terminating NULL if all was
|
---|
334 | successful.
|
---|
335 |
|
---|
336 | @retval EFI_SUCCESS The results have been distributed or are
|
---|
337 | awaiting distribution.
|
---|
338 |
|
---|
339 | @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
|
---|
340 | parts of the results that must be
|
---|
341 | stored awaiting possible future
|
---|
342 | protocols.
|
---|
343 |
|
---|
344 | @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
|
---|
345 | Results parameter would result
|
---|
346 | in this type of error.
|
---|
347 |
|
---|
348 | @retval EFI_NOT_FOUND Target for the specified routing data
|
---|
349 | was not found.
|
---|
350 |
|
---|
351 | **/
|
---|
352 | EFI_STATUS
|
---|
353 | EFIAPI
|
---|
354 | HttpBootFormRouteConfig (
|
---|
355 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
356 | IN CONST EFI_STRING Configuration,
|
---|
357 | OUT EFI_STRING *Progress
|
---|
358 | )
|
---|
359 | {
|
---|
360 | EFI_STATUS Status;
|
---|
361 | UINTN BufferSize;
|
---|
362 | HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
---|
363 | HTTP_BOOT_PRIVATE_DATA *Private;
|
---|
364 |
|
---|
365 | if (Progress == NULL) {
|
---|
366 | return EFI_INVALID_PARAMETER;
|
---|
367 | }
|
---|
368 | *Progress = Configuration;
|
---|
369 |
|
---|
370 | if (Configuration == NULL) {
|
---|
371 | return EFI_INVALID_PARAMETER;
|
---|
372 | }
|
---|
373 |
|
---|
374 | //
|
---|
375 | // Check routing data in <ConfigHdr>.
|
---|
376 | // Note: there is no name for Name/Value storage, only GUID will be checked
|
---|
377 | //
|
---|
378 | if (!HiiIsConfigHdrMatch (Configuration, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
|
---|
379 | return EFI_NOT_FOUND;
|
---|
380 | }
|
---|
381 |
|
---|
382 | CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
---|
383 | Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);
|
---|
384 |
|
---|
385 | BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
|
---|
386 | ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
|
---|
387 |
|
---|
388 | Status = gHiiConfigRouting->ConfigToBlock (
|
---|
389 | gHiiConfigRouting,
|
---|
390 | Configuration,
|
---|
391 | (UINT8 *) &CallbackInfo->HttpBootNvData,
|
---|
392 | &BufferSize,
|
---|
393 | Progress
|
---|
394 | );
|
---|
395 | if (EFI_ERROR (Status)) {
|
---|
396 | return Status;
|
---|
397 | }
|
---|
398 |
|
---|
399 | //
|
---|
400 | // Create a new boot option according to the configuration data.
|
---|
401 | //
|
---|
402 | HttpBootAddBootOption (
|
---|
403 | Private,
|
---|
404 | (CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE,
|
---|
405 | CallbackInfo->HttpBootNvData.Description,
|
---|
406 | CallbackInfo->HttpBootNvData.Uri
|
---|
407 | );
|
---|
408 |
|
---|
409 | return EFI_SUCCESS;
|
---|
410 | }
|
---|
411 |
|
---|
412 | /**
|
---|
413 |
|
---|
414 | This function is called to provide results data to the driver.
|
---|
415 | This data consists of a unique key that is used to identify
|
---|
416 | which data is either being passed back or being asked for.
|
---|
417 |
|
---|
418 | @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
419 | @param[in] Action Specifies the type of action taken by the browser.
|
---|
420 | @param[in] QuestionId A unique value which is sent to the original
|
---|
421 | exporting driver so that it can identify the type
|
---|
422 | of data to expect. The format of the data tends to
|
---|
423 | vary based on the opcode that generated the callback.
|
---|
424 | @param[in] Type The type of value for the question.
|
---|
425 | @param[in, out] Value A pointer to the data being sent to the original
|
---|
426 | exporting driver.
|
---|
427 | @param[out] ActionRequest On return, points to the action requested by the
|
---|
428 | callback function.
|
---|
429 |
|
---|
430 | @retval EFI_SUCCESS The callback successfully handled the action.
|
---|
431 | @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
|
---|
432 | variable and its data.
|
---|
433 | @retval EFI_DEVICE_ERROR The variable could not be saved.
|
---|
434 | @retval EFI_UNSUPPORTED The specified Action is not supported by the
|
---|
435 | callback.
|
---|
436 | **/
|
---|
437 | EFI_STATUS
|
---|
438 | EFIAPI
|
---|
439 | HttpBootFormCallback (
|
---|
440 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
441 | IN EFI_BROWSER_ACTION Action,
|
---|
442 | IN EFI_QUESTION_ID QuestionId,
|
---|
443 | IN UINT8 Type,
|
---|
444 | IN OUT EFI_IFR_TYPE_VALUE *Value,
|
---|
445 | OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
---|
446 | )
|
---|
447 | {
|
---|
448 | EFI_INPUT_KEY Key;
|
---|
449 | CHAR16 *Uri;
|
---|
450 | UINTN UriLen;
|
---|
451 | CHAR8 *AsciiUri;
|
---|
452 | HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
---|
453 | EFI_STATUS Status;
|
---|
454 |
|
---|
455 | Uri = NULL;
|
---|
456 | UriLen = 0;
|
---|
457 | AsciiUri = NULL;
|
---|
458 | Status = EFI_SUCCESS;
|
---|
459 |
|
---|
460 | if (This == NULL || Value == NULL) {
|
---|
461 | return EFI_INVALID_PARAMETER;
|
---|
462 | }
|
---|
463 |
|
---|
464 | CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
---|
465 |
|
---|
466 | if (Action != EFI_BROWSER_ACTION_CHANGING) {
|
---|
467 | return EFI_UNSUPPORTED;
|
---|
468 | }
|
---|
469 |
|
---|
470 | switch (QuestionId) {
|
---|
471 | case KEY_INITIATOR_URI:
|
---|
472 | //
|
---|
473 | // Get user input URI string
|
---|
474 | //
|
---|
475 | Uri = HiiGetString (CallbackInfo->RegisteredHandle, Value->string, NULL);
|
---|
476 |
|
---|
477 | //
|
---|
478 | // The URI should be either an empty string (for corporate environment) ,or http(s) for home environment.
|
---|
479 | // Pop up a message box for the unsupported URI.
|
---|
480 | //
|
---|
481 | if (StrLen (Uri) != 0) {
|
---|
482 | UriLen = StrLen (Uri) + 1;
|
---|
483 | AsciiUri = AllocateZeroPool (UriLen);
|
---|
484 | if (AsciiUri == NULL) {
|
---|
485 | FreePool (Uri);
|
---|
486 | return EFI_OUT_OF_RESOURCES;
|
---|
487 | }
|
---|
488 |
|
---|
489 | UnicodeStrToAsciiStrS (Uri, AsciiUri, UriLen);
|
---|
490 |
|
---|
491 | Status = HttpBootCheckUriScheme (AsciiUri);
|
---|
492 |
|
---|
493 | if (Status == EFI_INVALID_PARAMETER) {
|
---|
494 |
|
---|
495 | DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));
|
---|
496 |
|
---|
497 | CreatePopUp (
|
---|
498 | EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
---|
499 | &Key,
|
---|
500 | L"ERROR: Unsupported URI!",
|
---|
501 | L"Only supports HTTP and HTTPS",
|
---|
502 | NULL
|
---|
503 | );
|
---|
504 | } else if (Status == EFI_ACCESS_DENIED) {
|
---|
505 |
|
---|
506 | DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));
|
---|
507 |
|
---|
508 | CreatePopUp (
|
---|
509 | EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
---|
510 | &Key,
|
---|
511 | L"ERROR: Unsupported URI!",
|
---|
512 | L"HTTP is disabled",
|
---|
513 | NULL
|
---|
514 | );
|
---|
515 | }
|
---|
516 | }
|
---|
517 |
|
---|
518 | if (Uri != NULL) {
|
---|
519 | FreePool (Uri);
|
---|
520 | }
|
---|
521 |
|
---|
522 | if (AsciiUri != NULL) {
|
---|
523 | FreePool (AsciiUri);
|
---|
524 | }
|
---|
525 |
|
---|
526 | break;
|
---|
527 |
|
---|
528 | default:
|
---|
529 | break;
|
---|
530 | }
|
---|
531 |
|
---|
532 | return Status;
|
---|
533 | }
|
---|
534 |
|
---|
535 | /**
|
---|
536 | Initialize the configuration form.
|
---|
537 |
|
---|
538 | @param[in] Private Pointer to the driver private data.
|
---|
539 |
|
---|
540 | @retval EFI_SUCCESS The configuration form is initialized.
|
---|
541 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
---|
542 |
|
---|
543 | **/
|
---|
544 | EFI_STATUS
|
---|
545 | HttpBootConfigFormInit (
|
---|
546 | IN HTTP_BOOT_PRIVATE_DATA *Private
|
---|
547 | )
|
---|
548 | {
|
---|
549 | EFI_STATUS Status;
|
---|
550 | HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
---|
551 | VENDOR_DEVICE_PATH VendorDeviceNode;
|
---|
552 | CHAR16 *MacString;
|
---|
553 | CHAR16 *OldMenuString;
|
---|
554 | CHAR16 MenuString[128];
|
---|
555 |
|
---|
556 | CallbackInfo = &Private->CallbackInfo;
|
---|
557 |
|
---|
558 | if (CallbackInfo->Initilized) {
|
---|
559 | return EFI_SUCCESS;
|
---|
560 | }
|
---|
561 |
|
---|
562 | CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;
|
---|
563 |
|
---|
564 | //
|
---|
565 | // Construct device path node for EFI HII Config Access protocol,
|
---|
566 | // which consists of controller physical device path and one hardware
|
---|
567 | // vendor guid node.
|
---|
568 | //
|
---|
569 | ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
|
---|
570 | VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
|
---|
571 | VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
|
---|
572 | CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
|
---|
573 | SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
|
---|
574 | CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
|
---|
575 | Private->ParentDevicePath,
|
---|
576 | (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode
|
---|
577 | );
|
---|
578 | if (CallbackInfo->HiiVendorDevicePath == NULL) {
|
---|
579 | Status = EFI_OUT_OF_RESOURCES;
|
---|
580 | goto Error;
|
---|
581 | }
|
---|
582 |
|
---|
583 | CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;
|
---|
584 | CallbackInfo->ConfigAccess.RouteConfig = HttpBootFormRouteConfig;
|
---|
585 | CallbackInfo->ConfigAccess.Callback = HttpBootFormCallback;
|
---|
586 |
|
---|
587 | //
|
---|
588 | // Install Device Path Protocol and Config Access protocol to driver handle.
|
---|
589 | //
|
---|
590 | Status = gBS->InstallMultipleProtocolInterfaces (
|
---|
591 | &CallbackInfo->ChildHandle,
|
---|
592 | &gEfiDevicePathProtocolGuid,
|
---|
593 | CallbackInfo->HiiVendorDevicePath,
|
---|
594 | &gEfiHiiConfigAccessProtocolGuid,
|
---|
595 | &CallbackInfo->ConfigAccess,
|
---|
596 | NULL
|
---|
597 | );
|
---|
598 | if (EFI_ERROR (Status)) {
|
---|
599 | goto Error;
|
---|
600 | }
|
---|
601 |
|
---|
602 | //
|
---|
603 | // Publish our HII data.
|
---|
604 | //
|
---|
605 | CallbackInfo->RegisteredHandle = HiiAddPackages (
|
---|
606 | &gHttpBootConfigGuid,
|
---|
607 | CallbackInfo->ChildHandle,
|
---|
608 | HttpBootDxeStrings,
|
---|
609 | HttpBootConfigVfrBin,
|
---|
610 | NULL
|
---|
611 | );
|
---|
612 | if (CallbackInfo->RegisteredHandle == NULL) {
|
---|
613 | Status = EFI_OUT_OF_RESOURCES;
|
---|
614 | goto Error;
|
---|
615 | }
|
---|
616 |
|
---|
617 | //
|
---|
618 | // Append MAC string in the menu help string
|
---|
619 | //
|
---|
620 | Status = NetLibGetMacString (Private->Controller, NULL, &MacString);
|
---|
621 | if (!EFI_ERROR (Status)) {
|
---|
622 | OldMenuString = HiiGetString (
|
---|
623 | CallbackInfo->RegisteredHandle,
|
---|
624 | STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
|
---|
625 | NULL
|
---|
626 | );
|
---|
627 | UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
|
---|
628 | HiiSetString (
|
---|
629 | CallbackInfo->RegisteredHandle,
|
---|
630 | STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
|
---|
631 | MenuString,
|
---|
632 | NULL
|
---|
633 | );
|
---|
634 |
|
---|
635 | FreePool (MacString);
|
---|
636 | FreePool (OldMenuString);
|
---|
637 |
|
---|
638 | CallbackInfo->Initilized = TRUE;
|
---|
639 | return EFI_SUCCESS;
|
---|
640 | }
|
---|
641 |
|
---|
642 | Error:
|
---|
643 |
|
---|
644 | HttpBootConfigFormUnload (Private);
|
---|
645 | return Status;
|
---|
646 | }
|
---|
647 |
|
---|
648 | /**
|
---|
649 | Unload the configuration form, this includes: delete all the configuration
|
---|
650 | entries, uninstall the form callback protocol, and free the resources used.
|
---|
651 | The form will only be unload completely when both IP4 and IP6 stack are stopped.
|
---|
652 |
|
---|
653 | @param[in] Private Pointer to the driver private data.
|
---|
654 |
|
---|
655 | @retval EFI_SUCCESS The configuration form is unloaded.
|
---|
656 | @retval Others Failed to unload the form.
|
---|
657 |
|
---|
658 | **/
|
---|
659 | EFI_STATUS
|
---|
660 | HttpBootConfigFormUnload (
|
---|
661 | IN HTTP_BOOT_PRIVATE_DATA *Private
|
---|
662 | )
|
---|
663 | {
|
---|
664 | HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
---|
665 |
|
---|
666 | if (Private->Ip4Nic != NULL || Private->Ip6Nic != NULL) {
|
---|
667 | //
|
---|
668 | // Only unload the configuration form when both IP4 and IP6 stack are stopped.
|
---|
669 | //
|
---|
670 | return EFI_SUCCESS;
|
---|
671 | }
|
---|
672 |
|
---|
673 | CallbackInfo = &Private->CallbackInfo;
|
---|
674 | if (CallbackInfo->ChildHandle != NULL) {
|
---|
675 | //
|
---|
676 | // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
|
---|
677 | //
|
---|
678 | gBS->UninstallMultipleProtocolInterfaces (
|
---|
679 | CallbackInfo->ChildHandle,
|
---|
680 | &gEfiDevicePathProtocolGuid,
|
---|
681 | CallbackInfo->HiiVendorDevicePath,
|
---|
682 | &gEfiHiiConfigAccessProtocolGuid,
|
---|
683 | &CallbackInfo->ConfigAccess,
|
---|
684 | NULL
|
---|
685 | );
|
---|
686 | CallbackInfo->ChildHandle = NULL;
|
---|
687 | }
|
---|
688 |
|
---|
689 | if (CallbackInfo->HiiVendorDevicePath != NULL) {
|
---|
690 | FreePool (CallbackInfo->HiiVendorDevicePath);
|
---|
691 | CallbackInfo->HiiVendorDevicePath = NULL;
|
---|
692 | }
|
---|
693 |
|
---|
694 | if (CallbackInfo->RegisteredHandle != NULL) {
|
---|
695 | //
|
---|
696 | // Remove HII package list
|
---|
697 | //
|
---|
698 | HiiRemovePackages (CallbackInfo->RegisteredHandle);
|
---|
699 | CallbackInfo->RegisteredHandle = NULL;
|
---|
700 | }
|
---|
701 |
|
---|
702 | return EFI_SUCCESS;
|
---|
703 | }
|
---|