]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/HttpDxe/HttpDriver.c
NetworkPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpDriver.c
1 /** @file
2 The driver binding and service binding protocol for HttpDxe driver.
3
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "HttpDriver.h"
12
13 EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities = NULL;
14
15 ///
16 /// Driver Binding Protocol instance
17 ///
18 EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp4DriverBinding = {
19 HttpDxeIp4DriverBindingSupported,
20 HttpDxeIp4DriverBindingStart,
21 HttpDxeIp4DriverBindingStop,
22 HTTP_DRIVER_VERSION,
23 NULL,
24 NULL
25 };
26
27 EFI_DRIVER_BINDING_PROTOCOL gHttpDxeIp6DriverBinding = {
28 HttpDxeIp6DriverBindingSupported,
29 HttpDxeIp6DriverBindingStart,
30 HttpDxeIp6DriverBindingStop,
31 HTTP_DRIVER_VERSION,
32 NULL,
33 NULL
34 };
35
36
37 /**
38 Create a HTTP driver service binding private instance.
39
40 @param[in] Controller The controller that has TCP4 service binding
41 installed.
42 @param[out] ServiceData Point to HTTP driver private instance.
43
44 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
45 @retval EFI_SUCCESS A new HTTP driver private instance is created.
46
47 **/
48 EFI_STATUS
49 HttpCreateService (
50 IN EFI_HANDLE Controller,
51 OUT HTTP_SERVICE **ServiceData
52 )
53 {
54 HTTP_SERVICE *HttpService;
55
56 ASSERT (ServiceData != NULL);
57 *ServiceData = NULL;
58
59 HttpService = AllocateZeroPool (sizeof (HTTP_SERVICE));
60 if (HttpService == NULL) {
61 return EFI_OUT_OF_RESOURCES;
62 }
63
64 HttpService->Signature = HTTP_SERVICE_SIGNATURE;
65 HttpService->ServiceBinding.CreateChild = HttpServiceBindingCreateChild;
66 HttpService->ServiceBinding.DestroyChild = HttpServiceBindingDestroyChild;
67 HttpService->ControllerHandle = Controller;
68 HttpService->ChildrenNumber = 0;
69 InitializeListHead (&HttpService->ChildrenList);
70
71 *ServiceData = HttpService;
72 return EFI_SUCCESS;
73 }
74
75 /**
76 Release all the resource used the HTTP service binding instance.
77
78 @param[in] HttpService The HTTP private instance.
79 @param[in] UsingIpv6 Indicate use TCP4 protocol or TCP6 protocol.
80 if TRUE, use Tcp6 protocol.
81 if FALSE, use Tcp4 protocl.
82 **/
83 VOID
84 HttpCleanService (
85 IN HTTP_SERVICE *HttpService,
86 IN BOOLEAN UsingIpv6
87 )
88 {
89
90 if (HttpService == NULL) {
91 return ;
92 }
93 if (!UsingIpv6) {
94 if (HttpService->Tcp4ChildHandle != NULL) {
95 gBS->CloseProtocol (
96 HttpService->Tcp4ChildHandle,
97 &gEfiTcp4ProtocolGuid,
98 HttpService->Ip4DriverBindingHandle,
99 HttpService->ControllerHandle
100 );
101
102 NetLibDestroyServiceChild (
103 HttpService->ControllerHandle,
104 HttpService->Ip4DriverBindingHandle,
105 &gEfiTcp4ServiceBindingProtocolGuid,
106 HttpService->Tcp4ChildHandle
107 );
108
109 HttpService->Tcp4ChildHandle = NULL;
110 }
111 } else {
112 if (HttpService->Tcp6ChildHandle != NULL) {
113 gBS->CloseProtocol (
114 HttpService->Tcp6ChildHandle,
115 &gEfiTcp6ProtocolGuid,
116 HttpService->Ip6DriverBindingHandle,
117 HttpService->ControllerHandle
118 );
119
120 NetLibDestroyServiceChild (
121 HttpService->ControllerHandle,
122 HttpService->Ip6DriverBindingHandle,
123 &gEfiTcp6ServiceBindingProtocolGuid,
124 HttpService->Tcp6ChildHandle
125 );
126
127 HttpService->Tcp6ChildHandle = NULL;
128 }
129 }
130
131 }
132
133 /**
134 The event process routine when the http utilities protocol is installed
135 in the system.
136
137 @param[in] Event Not used.
138 @param[in] Context The pointer to the IP4 config2 instance data or IP6 Config instance data.
139
140 **/
141 VOID
142 EFIAPI
143 HttpUtilitiesInstalledCallback (
144 IN EFI_EVENT Event,
145 IN VOID *Context
146 )
147 {
148 gBS->LocateProtocol (
149 &gEfiHttpUtilitiesProtocolGuid,
150 NULL,
151 (VOID **) &mHttpUtilities
152 );
153
154 //
155 // Close the event if Http utilities protocol is loacted.
156 //
157 if (mHttpUtilities != NULL && Event != NULL) {
158 gBS->CloseEvent (Event);
159 }
160 }
161
162 /**
163 This is the declaration of an EFI image entry point. This entry point is
164 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
165 both device drivers and bus drivers.
166
167 @param ImageHandle The firmware allocated handle for the UEFI image.
168 @param SystemTable A pointer to the EFI System Table.
169
170 @retval EFI_SUCCESS The operation completed successfully.
171 @retval Others An unexpected error occurred.
172
173 **/
174 EFI_STATUS
175 EFIAPI
176 HttpDxeDriverEntryPoint (
177 IN EFI_HANDLE ImageHandle,
178 IN EFI_SYSTEM_TABLE *SystemTable
179 )
180 {
181 EFI_STATUS Status;
182 VOID *Registration;
183
184 gBS->LocateProtocol (
185 &gEfiHttpUtilitiesProtocolGuid,
186 NULL,
187 (VOID **) &mHttpUtilities
188 );
189
190 if (mHttpUtilities == NULL) {
191 //
192 // No Http utilities protocol, register a notify.
193 //
194 EfiCreateProtocolNotifyEvent (
195 &gEfiHttpUtilitiesProtocolGuid,
196 TPL_CALLBACK,
197 HttpUtilitiesInstalledCallback,
198 NULL,
199 &Registration
200 );
201 }
202
203 //
204 // Install UEFI Driver Model protocol(s).
205 //
206 Status = EfiLibInstallDriverBindingComponentName2 (
207 ImageHandle,
208 SystemTable,
209 &gHttpDxeIp4DriverBinding,
210 ImageHandle,
211 &gHttpDxeComponentName,
212 &gHttpDxeComponentName2
213 );
214 if (EFI_ERROR (Status)) {
215 return Status;
216 }
217
218 Status = EfiLibInstallDriverBindingComponentName2 (
219 ImageHandle,
220 SystemTable,
221 &gHttpDxeIp6DriverBinding,
222 NULL,
223 &gHttpDxeComponentName,
224 &gHttpDxeComponentName2
225 );
226 if (EFI_ERROR (Status)) {
227 EfiLibUninstallDriverBindingComponentName2 (
228 &gHttpDxeIp4DriverBinding,
229 &gHttpDxeComponentName,
230 &gHttpDxeComponentName2
231 );
232 }
233 return Status;
234 }
235
236 /**
237 Callback function which provided by user to remove one node in NetDestroyLinkList process.
238
239 @param[in] Entry The entry to be removed.
240 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
241
242 @retval EFI_INVALID_PARAMETER Any input parameter is NULL.
243 @retval EFI_SUCCESS The entry has been removed successfully.
244 @retval Others Fail to remove the entry.
245
246 **/
247 EFI_STATUS
248 EFIAPI
249 HttpDestroyChildEntryInHandleBuffer (
250 IN LIST_ENTRY *Entry,
251 IN VOID *Context
252 )
253 {
254 HTTP_PROTOCOL *HttpInstance;
255 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
256 UINTN NumberOfChildren;
257 EFI_HANDLE *ChildHandleBuffer;
258
259 if (Entry == NULL || Context == NULL) {
260 return EFI_INVALID_PARAMETER;
261 }
262
263 HttpInstance = NET_LIST_USER_STRUCT_S (Entry, HTTP_PROTOCOL, Link, HTTP_PROTOCOL_SIGNATURE);
264 ServiceBinding = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
265 NumberOfChildren = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
266 ChildHandleBuffer = ((HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
267
268 if (!NetIsInHandleBuffer (HttpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
269 return EFI_SUCCESS;
270 }
271
272 return ServiceBinding->DestroyChild (ServiceBinding, HttpInstance->Handle);
273 }
274
275 /**
276 Test to see if this driver supports ControllerHandle. This is the worker function for
277 HttpDxeIp4(6)DriverBindingSupported.
278
279 @param[in] This The pointer to the driver binding protocol.
280 @param[in] ControllerHandle The handle of device to be tested.
281 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
282 device to be started.
283 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
284
285 @retval EFI_SUCCESS This driver supports this device.
286 @retval EFI_UNSUPPORTED This driver does not support this device.
287
288 **/
289 EFI_STATUS
290 EFIAPI
291 HttpDxeSupported (
292 IN EFI_DRIVER_BINDING_PROTOCOL *This,
293 IN EFI_HANDLE ControllerHandle,
294 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
295 IN UINT8 IpVersion
296 )
297 {
298 EFI_STATUS Status;
299 EFI_GUID *TcpServiceBindingProtocolGuid;
300
301 if (IpVersion == IP_VERSION_4) {
302 TcpServiceBindingProtocolGuid = &gEfiTcp4ServiceBindingProtocolGuid;
303 } else {
304 TcpServiceBindingProtocolGuid = &gEfiTcp6ServiceBindingProtocolGuid;
305 }
306
307 Status = gBS->OpenProtocol (
308 ControllerHandle,
309 TcpServiceBindingProtocolGuid,
310 NULL,
311 This->DriverBindingHandle,
312 ControllerHandle,
313 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
314 );
315
316 if (EFI_ERROR (Status)) {
317 return EFI_UNSUPPORTED;
318 }
319
320 return EFI_SUCCESS;
321 }
322
323 /**
324 Start this driver on ControllerHandle. This is the worker function for
325 HttpDxeIp4(6)DriverBindingStart.
326
327 @param[in] This The pointer to the driver binding protocol.
328 @param[in] ControllerHandle The handle of device to be started.
329 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
330 device to be started.
331 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
332
333
334 @retval EFI_SUCCESS This driver is installed to ControllerHandle.
335 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
336 @retval other This driver does not support this device.
337
338 **/
339 EFI_STATUS
340 EFIAPI
341 HttpDxeStart (
342 IN EFI_DRIVER_BINDING_PROTOCOL *This,
343 IN EFI_HANDLE ControllerHandle,
344 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
345 IN UINT8 IpVersion
346 )
347 {
348 EFI_STATUS Status;
349 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
350 HTTP_SERVICE *HttpService;
351 VOID *Interface;
352 BOOLEAN UsingIpv6;
353
354 UsingIpv6 = FALSE;
355
356 //
357 // Test for the Http service binding protocol
358 //
359 Status = gBS->OpenProtocol (
360 ControllerHandle,
361 &gEfiHttpServiceBindingProtocolGuid,
362 (VOID **) &ServiceBinding,
363 This->DriverBindingHandle,
364 ControllerHandle,
365 EFI_OPEN_PROTOCOL_GET_PROTOCOL
366 );
367
368 if (!EFI_ERROR (Status)) {
369 HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
370 } else {
371 Status = HttpCreateService (ControllerHandle, &HttpService);
372 if (EFI_ERROR (Status)) {
373 return Status;
374 }
375
376 ASSERT (HttpService != NULL);
377
378 //
379 // Install the HttpServiceBinding Protocol onto Controller
380 //
381 Status = gBS->InstallMultipleProtocolInterfaces (
382 &ControllerHandle,
383 &gEfiHttpServiceBindingProtocolGuid,
384 &HttpService->ServiceBinding,
385 NULL
386 );
387
388 if (EFI_ERROR (Status)) {
389 goto ON_ERROR;
390 }
391 }
392
393 if (IpVersion == IP_VERSION_4) {
394 HttpService->Ip4DriverBindingHandle = This->DriverBindingHandle;
395
396 if (HttpService->Tcp4ChildHandle == NULL) {
397 //
398 // Create a TCP4 child instance, but do not configure it. This will establish the parent-child relationship.
399 //
400 Status = NetLibCreateServiceChild (
401 ControllerHandle,
402 This->DriverBindingHandle,
403 &gEfiTcp4ServiceBindingProtocolGuid,
404 &HttpService->Tcp4ChildHandle
405 );
406
407 if (EFI_ERROR (Status)) {
408 goto ON_ERROR;
409 }
410
411 Status = gBS->OpenProtocol (
412 HttpService->Tcp4ChildHandle,
413 &gEfiTcp4ProtocolGuid,
414 &Interface,
415 This->DriverBindingHandle,
416 ControllerHandle,
417 EFI_OPEN_PROTOCOL_BY_DRIVER
418 );
419
420 if (EFI_ERROR (Status)) {
421 goto ON_ERROR;
422 }
423
424 } else {
425 return EFI_ALREADY_STARTED;
426 }
427
428 } else {
429 UsingIpv6 = TRUE;
430 HttpService->Ip6DriverBindingHandle = This->DriverBindingHandle;
431
432 if (HttpService->Tcp6ChildHandle == NULL) {
433 //
434 // Create a TCP6 child instance, but do not configure it. This will establish the parent-child relationship.
435 //
436 Status = NetLibCreateServiceChild (
437 ControllerHandle,
438 This->DriverBindingHandle,
439 &gEfiTcp6ServiceBindingProtocolGuid,
440 &HttpService->Tcp6ChildHandle
441 );
442
443 if (EFI_ERROR (Status)) {
444 goto ON_ERROR;
445 }
446
447 Status = gBS->OpenProtocol (
448 HttpService->Tcp6ChildHandle,
449 &gEfiTcp6ProtocolGuid,
450 &Interface,
451 This->DriverBindingHandle,
452 ControllerHandle,
453 EFI_OPEN_PROTOCOL_BY_DRIVER
454 );
455
456 if (EFI_ERROR (Status)) {
457 goto ON_ERROR;
458 }
459
460 } else {
461 return EFI_ALREADY_STARTED;
462 }
463
464 }
465
466 return EFI_SUCCESS;
467
468 ON_ERROR:
469
470 if (HttpService != NULL) {
471 HttpCleanService (HttpService, UsingIpv6);
472 if (HttpService->Tcp4ChildHandle == NULL && HttpService->Tcp6ChildHandle == NULL) {
473 FreePool (HttpService);
474 }
475 }
476
477 return Status;
478
479
480 }
481
482 /**
483 Stop this driver on ControllerHandle. This is the worker function for
484 HttpDxeIp4(6)DriverBindingStop.
485
486 @param[in] This Protocol instance pointer.
487 @param[in] ControllerHandle Handle of device to stop driver on.
488 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
489 children is zero stop the entire bus driver.
490 @param[in] ChildHandleBuffer List of Child Handles to Stop.
491 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
492
493 @retval EFI_SUCCESS This driver was removed ControllerHandle.
494 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
495 @retval Others This driver was not removed from this device
496
497 **/
498 EFI_STATUS
499 EFIAPI
500 HttpDxeStop (
501 IN EFI_DRIVER_BINDING_PROTOCOL *This,
502 IN EFI_HANDLE ControllerHandle,
503 IN UINTN NumberOfChildren,
504 IN EFI_HANDLE *ChildHandleBuffer,
505 IN UINT8 IpVersion
506 )
507 {
508 EFI_HANDLE NicHandle;
509 EFI_STATUS Status;
510 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
511 HTTP_SERVICE *HttpService;
512 LIST_ENTRY *List;
513 HTTP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
514 BOOLEAN UsingIpv6;
515
516 //
517 // HTTP driver opens TCP4(6) child, So, Controller is a TCP4(6)
518 // child handle. Locate the Nic handle first. Then get the
519 // HTTP private data back.
520 //
521 if (IpVersion == IP_VERSION_4) {
522 UsingIpv6 = FALSE;
523 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
524 } else {
525 UsingIpv6 = TRUE;
526 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
527 }
528
529 if (NicHandle == NULL) {
530 return EFI_SUCCESS;
531 }
532
533 Status = gBS->OpenProtocol (
534 NicHandle,
535 &gEfiHttpServiceBindingProtocolGuid,
536 (VOID **) &ServiceBinding,
537 This->DriverBindingHandle,
538 NicHandle,
539 EFI_OPEN_PROTOCOL_GET_PROTOCOL
540 );
541
542 if (!EFI_ERROR (Status)) {
543
544 HttpService = HTTP_SERVICE_FROM_PROTOCOL (ServiceBinding);
545
546 if (NumberOfChildren != 0) {
547 //
548 // Destroy the HTTP child instance in ChildHandleBuffer.
549 //
550 List = &HttpService->ChildrenList;
551 Context.ServiceBinding = ServiceBinding;
552 Context.NumberOfChildren = NumberOfChildren;
553 Context.ChildHandleBuffer = ChildHandleBuffer;
554 Status = NetDestroyLinkList (
555 List,
556 HttpDestroyChildEntryInHandleBuffer,
557 &Context,
558 NULL
559 );
560 } else {
561
562 HttpCleanService (HttpService, UsingIpv6);
563
564 if (HttpService->Tcp4ChildHandle == NULL && HttpService->Tcp6ChildHandle == NULL) {
565 gBS->UninstallProtocolInterface (
566 NicHandle,
567 &gEfiHttpServiceBindingProtocolGuid,
568 ServiceBinding
569 );
570 FreePool (HttpService);
571 }
572 Status = EFI_SUCCESS;
573 }
574 }
575
576 return Status;
577
578 }
579
580 /**
581 Tests to see if this driver supports a given controller. If a child device is provided,
582 it further tests to see if this driver supports creating a handle for the specified child device.
583
584 This function checks to see if the driver specified by This supports the device specified by
585 ControllerHandle. Drivers will typically use the device path attached to
586 ControllerHandle and/or the services from the bus I/O abstraction attached to
587 ControllerHandle to determine if the driver supports ControllerHandle. This function
588 may be called many times during platform initialization. In order to reduce boot times, the tests
589 performed by this function must be very small, and take as little time as possible to execute. This
590 function must not change the state of any hardware devices, and this function must be aware that the
591 device specified by ControllerHandle may already be managed by the same driver or a
592 different driver. This function must match its calls to AllocatePages() with FreePages(),
593 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
594 Because ControllerHandle may have been previously started by the same driver, if a protocol is
595 already in the opened state, then it must not be closed with CloseProtocol(). This is required
596 to guarantee the state of ControllerHandle is not modified by this function.
597
598 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
599 @param[in] ControllerHandle The handle of the controller to test. This handle
600 must support a protocol interface that supplies
601 an I/O abstraction to the driver.
602 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
603 parameter is ignored by device drivers, and is optional for bus
604 drivers. For bus drivers, if this parameter is not NULL, then
605 the bus driver must determine if the bus controller specified
606 by ControllerHandle and the child controller specified
607 by RemainingDevicePath are both supported by this
608 bus driver.
609
610 @retval EFI_SUCCESS The device specified by ControllerHandle and
611 RemainingDevicePath is supported by the driver specified by This.
612 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
613 RemainingDevicePath is already being managed by the driver
614 specified by This.
615 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
616 RemainingDevicePath is already being managed by a different
617 driver or an application that requires exclusive access.
618 Currently not implemented.
619 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
620 RemainingDevicePath is not supported by the driver specified by This.
621 **/
622 EFI_STATUS
623 EFIAPI
624 HttpDxeIp4DriverBindingSupported (
625 IN EFI_DRIVER_BINDING_PROTOCOL *This,
626 IN EFI_HANDLE ControllerHandle,
627 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
628 )
629 {
630 return HttpDxeSupported (
631 This,
632 ControllerHandle,
633 RemainingDevicePath,
634 IP_VERSION_4
635 );
636 }
637
638 /**
639 Starts a device controller or a bus controller.
640
641 The Start() function is designed to be invoked from the EFI boot service ConnectController().
642 As a result, much of the error checking on the parameters to Start() has been moved into this
643 common boot service. It is legal to call Start() from other locations,
644 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
645 1. ControllerHandle must be a valid EFI_HANDLE.
646 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
647 EFI_DEVICE_PATH_PROTOCOL.
648 3. Prior to calling Start(), the Supported() function for the driver specified by This must
649 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
650
651 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
652 @param[in] ControllerHandle The handle of the controller to start. This handle
653 must support a protocol interface that supplies
654 an I/O abstraction to the driver.
655 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
656 parameter is ignored by device drivers, and is optional for bus
657 drivers. For a bus driver, if this parameter is NULL, then handles
658 for all the children of Controller are created by this driver.
659 If this parameter is not NULL and the first Device Path Node is
660 not the End of Device Path Node, then only the handle for the
661 child device specified by the first Device Path Node of
662 RemainingDevicePath is created by this driver.
663 If the first Device Path Node of RemainingDevicePath is
664 the End of Device Path Node, no child handle is created by this
665 driver.
666
667 @retval EFI_SUCCESS The device was started.
668 @retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
669 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
670 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
671 @retval Others The driver failded to start the device.
672
673 **/
674 EFI_STATUS
675 EFIAPI
676 HttpDxeIp4DriverBindingStart (
677 IN EFI_DRIVER_BINDING_PROTOCOL *This,
678 IN EFI_HANDLE ControllerHandle,
679 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
680 )
681 {
682 return HttpDxeStart (
683 This,
684 ControllerHandle,
685 RemainingDevicePath,
686 IP_VERSION_4
687 );
688 }
689
690 /**
691 Stops a device controller or a bus controller.
692
693 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
694 As a result, much of the error checking on the parameters to Stop() has been moved
695 into this common boot service. It is legal to call Stop() from other locations,
696 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
697 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
698 same driver's Start() function.
699 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
700 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
701 Start() function, and the Start() function must have called OpenProtocol() on
702 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
703
704 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
705 @param[in] ControllerHandle A handle to the device being stopped. The handle must
706 support a bus specific I/O protocol for the driver
707 to use to stop the device.
708 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
709 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
710 if NumberOfChildren is 0.
711
712 @retval EFI_SUCCESS The device was stopped.
713 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
714
715 **/
716 EFI_STATUS
717 EFIAPI
718 HttpDxeIp4DriverBindingStop (
719 IN EFI_DRIVER_BINDING_PROTOCOL *This,
720 IN EFI_HANDLE ControllerHandle,
721 IN UINTN NumberOfChildren,
722 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
723 )
724 {
725 return HttpDxeStop (
726 This,
727 ControllerHandle,
728 NumberOfChildren,
729 ChildHandleBuffer,
730 IP_VERSION_4
731 );
732 }
733
734 /**
735 Tests to see if this driver supports a given controller. If a child device is provided,
736 it further tests to see if this driver supports creating a handle for the specified child device.
737
738 This function checks to see if the driver specified by This supports the device specified by
739 ControllerHandle. Drivers will typically use the device path attached to
740 ControllerHandle and/or the services from the bus I/O abstraction attached to
741 ControllerHandle to determine if the driver supports ControllerHandle. This function
742 may be called many times during platform initialization. In order to reduce boot times, the tests
743 performed by this function must be very small, and take as little time as possible to execute. This
744 function must not change the state of any hardware devices, and this function must be aware that the
745 device specified by ControllerHandle may already be managed by the same driver or a
746 different driver. This function must match its calls to AllocatePages() with FreePages(),
747 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
748 Because ControllerHandle may have been previously started by the same driver, if a protocol is
749 already in the opened state, then it must not be closed with CloseProtocol(). This is required
750 to guarantee the state of ControllerHandle is not modified by this function.
751
752 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
753 @param[in] ControllerHandle The handle of the controller to test. This handle
754 must support a protocol interface that supplies
755 an I/O abstraction to the driver.
756 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
757 parameter is ignored by device drivers, and is optional for bus
758 drivers. For bus drivers, if this parameter is not NULL, then
759 the bus driver must determine if the bus controller specified
760 by ControllerHandle and the child controller specified
761 by RemainingDevicePath are both supported by this
762 bus driver.
763
764 @retval EFI_SUCCESS The device specified by ControllerHandle and
765 RemainingDevicePath is supported by the driver specified by This.
766 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
767 RemainingDevicePath is already being managed by the driver
768 specified by This.
769 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
770 RemainingDevicePath is already being managed by a different
771 driver or an application that requires exclusive access.
772 Currently not implemented.
773 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
774 RemainingDevicePath is not supported by the driver specified by This.
775 **/
776 EFI_STATUS
777 EFIAPI
778 HttpDxeIp6DriverBindingSupported (
779 IN EFI_DRIVER_BINDING_PROTOCOL *This,
780 IN EFI_HANDLE ControllerHandle,
781 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
782 )
783 {
784 return HttpDxeSupported (
785 This,
786 ControllerHandle,
787 RemainingDevicePath,
788 IP_VERSION_6
789 );
790
791 }
792
793 /**
794 Starts a device controller or a bus controller.
795
796 The Start() function is designed to be invoked from the EFI boot service ConnectController().
797 As a result, much of the error checking on the parameters to Start() has been moved into this
798 common boot service. It is legal to call Start() from other locations,
799 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
800 1. ControllerHandle must be a valid EFI_HANDLE.
801 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
802 EFI_DEVICE_PATH_PROTOCOL.
803 3. Prior to calling Start(), the Supported() function for the driver specified by This must
804 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
805
806 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
807 @param[in] ControllerHandle The handle of the controller to start. This handle
808 must support a protocol interface that supplies
809 an I/O abstraction to the driver.
810 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
811 parameter is ignored by device drivers, and is optional for bus
812 drivers. For a bus driver, if this parameter is NULL, then handles
813 for all the children of Controller are created by this driver.
814 If this parameter is not NULL and the first Device Path Node is
815 not the End of Device Path Node, then only the handle for the
816 child device specified by the first Device Path Node of
817 RemainingDevicePath is created by this driver.
818 If the first Device Path Node of RemainingDevicePath is
819 the End of Device Path Node, no child handle is created by this
820 driver.
821
822 @retval EFI_SUCCESS The device was started.
823 @retval EFI_ALREADY_STARTED This device is already running on ControllerHandle.
824 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
825 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
826 @retval Others The driver failded to start the device.
827
828 **/
829 EFI_STATUS
830 EFIAPI
831 HttpDxeIp6DriverBindingStart (
832 IN EFI_DRIVER_BINDING_PROTOCOL *This,
833 IN EFI_HANDLE ControllerHandle,
834 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
835 )
836 {
837 return HttpDxeStart (
838 This,
839 ControllerHandle,
840 RemainingDevicePath,
841 IP_VERSION_6
842 );
843 }
844
845 /**
846 Stops a device controller or a bus controller.
847
848 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
849 As a result, much of the error checking on the parameters to Stop() has been moved
850 into this common boot service. It is legal to call Stop() from other locations,
851 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
852 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
853 same driver's Start() function.
854 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
855 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
856 Start() function, and the Start() function must have called OpenProtocol() on
857 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
858
859 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
860 @param[in] ControllerHandle A handle to the device being stopped. The handle must
861 support a bus specific I/O protocol for the driver
862 to use to stop the device.
863 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
864 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
865 if NumberOfChildren is 0.
866
867 @retval EFI_SUCCESS The device was stopped.
868 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
869
870 **/
871 EFI_STATUS
872 EFIAPI
873 HttpDxeIp6DriverBindingStop (
874 IN EFI_DRIVER_BINDING_PROTOCOL *This,
875 IN EFI_HANDLE ControllerHandle,
876 IN UINTN NumberOfChildren,
877 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
878 )
879 {
880 return HttpDxeStop (
881 This,
882 ControllerHandle,
883 NumberOfChildren,
884 ChildHandleBuffer,
885 IP_VERSION_6
886 );
887 }
888 /**
889 Creates a child handle and installs a protocol.
890
891 The CreateChild() function installs a protocol on ChildHandle.
892 If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
893 If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
894
895 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
896 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
897 then a new handle is created. If it is a pointer to an existing UEFI handle,
898 then the protocol is added to the existing UEFI handle.
899
900 @retval EFI_SUCCES The protocol was added to ChildHandle.
901 @retval EFI_INVALID_PARAMETER This is NULL, or ChildHandle is NULL.
902 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
903 the child.
904 @retval other The child handle was not created.
905
906 **/
907 EFI_STATUS
908 EFIAPI
909 HttpServiceBindingCreateChild (
910 IN EFI_SERVICE_BINDING_PROTOCOL *This,
911 IN OUT EFI_HANDLE *ChildHandle
912 )
913 {
914 HTTP_SERVICE *HttpService;
915 HTTP_PROTOCOL *HttpInstance;
916 EFI_STATUS Status;
917 EFI_TPL OldTpl;
918
919 if ((This == NULL) || (ChildHandle == NULL)) {
920 return EFI_INVALID_PARAMETER;
921 }
922
923 HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
924 HttpInstance = AllocateZeroPool (sizeof (HTTP_PROTOCOL));
925 if (HttpInstance == NULL) {
926 return EFI_OUT_OF_RESOURCES;
927 }
928
929 HttpInstance->Signature = HTTP_PROTOCOL_SIGNATURE;
930 HttpInstance->Service = HttpService;
931 HttpInstance->Method = HttpMethodMax;
932
933 CopyMem (&HttpInstance->Http, &mEfiHttpTemplate, sizeof (HttpInstance->Http));
934 NetMapInit (&HttpInstance->TxTokens);
935 NetMapInit (&HttpInstance->RxTokens);
936
937 //
938 // Install HTTP protocol onto ChildHandle
939 //
940 Status = gBS->InstallMultipleProtocolInterfaces (
941 ChildHandle,
942 &gEfiHttpProtocolGuid,
943 &HttpInstance->Http,
944 NULL
945 );
946
947 if (EFI_ERROR (Status)) {
948 goto ON_ERROR;
949 }
950
951 HttpInstance->Handle = *ChildHandle;
952
953 //
954 // Add it to the HTTP service's child list.
955 //
956 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
957
958 InsertTailList (&HttpService->ChildrenList, &HttpInstance->Link);
959 HttpService->ChildrenNumber++;
960
961 gBS->RestoreTPL (OldTpl);
962
963 return EFI_SUCCESS;
964
965 ON_ERROR:
966
967 NetMapClean (&HttpInstance->TxTokens);
968 NetMapClean (&HttpInstance->RxTokens);
969 FreePool (HttpInstance);
970
971 return Status;
972 }
973
974 /**
975 Destroys a child handle with a protocol installed on it.
976
977 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
978 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
979 last protocol on ChildHandle, then ChildHandle is destroyed.
980
981 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
982 @param ChildHandle Handle of the child to destroy
983
984 @retval EFI_SUCCES The protocol was removed from ChildHandle.
985 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
986 @retval EFI_INVALID_PARAMETER Child handle is NULL.
987 @retval other The child handle was not destroyed
988
989 **/
990 EFI_STATUS
991 EFIAPI
992 HttpServiceBindingDestroyChild (
993 IN EFI_SERVICE_BINDING_PROTOCOL *This,
994 IN EFI_HANDLE ChildHandle
995 )
996 {
997 HTTP_SERVICE *HttpService;
998 HTTP_PROTOCOL *HttpInstance;
999 EFI_HTTP_PROTOCOL *Http;
1000 EFI_STATUS Status;
1001 EFI_TPL OldTpl;
1002
1003 if ((This == NULL) || (ChildHandle == NULL)) {
1004 return EFI_INVALID_PARAMETER;
1005 }
1006
1007 HttpService = HTTP_SERVICE_FROM_PROTOCOL (This);
1008 Status = gBS->OpenProtocol (
1009 ChildHandle,
1010 &gEfiHttpProtocolGuid,
1011 (VOID **) &Http,
1012 NULL,
1013 NULL,
1014 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1015 );
1016 if (EFI_ERROR (Status)) {
1017 return EFI_UNSUPPORTED;
1018 }
1019
1020 HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (Http);
1021 if (HttpInstance->Service != HttpService) {
1022 return EFI_INVALID_PARAMETER;
1023 }
1024
1025 if (HttpInstance->InDestroy) {
1026 return EFI_SUCCESS;
1027 }
1028
1029 HttpInstance->InDestroy = TRUE;
1030
1031 //
1032 // Uninstall the HTTP protocol.
1033 //
1034 Status = gBS->UninstallProtocolInterface (
1035 ChildHandle,
1036 &gEfiHttpProtocolGuid,
1037 Http
1038 );
1039
1040 if (EFI_ERROR (Status)) {
1041 HttpInstance->InDestroy = FALSE;
1042 return Status;
1043 }
1044
1045 HttpCleanProtocol (HttpInstance);
1046
1047 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1048
1049 RemoveEntryList (&HttpInstance->Link);
1050 HttpService->ChildrenNumber--;
1051
1052 gBS->RestoreTPL (OldTpl);
1053
1054 FreePool (HttpInstance);
1055 return EFI_SUCCESS;
1056 }