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