/** Destroy the HTTP child based on IPv4 stack. @param[in] This Pointer to the EFI_DRIVER_BINDING_PROTOCOL. @param[in] Private Pointer to HTTP_BOOT_PRIVATE_DATA. **/ VOID HttpBootDestroyIp4Children ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN HTTP_BOOT_PRIVATE_DATA *Private ) { ASSERT (This != NULL); ASSERT (Private != NULL); ASSERT (Private->UsingIpv6 == FALSE); if (Private->Dhcp4Child != NULL) { gBS->CloseProtocol ( Private->Dhcp4Child, &gEfiDhcp4ProtocolGuid, This->DriverBindingHandle, Private->Controller ); NetLibDestroyServiceChild ( Private->Controller, This->DriverBindingHandle, &gEfiDhcp4ServiceBindingProtocolGuid, Private->Dhcp4Child ); } if (Private->HttpCreated) { HttpIoDestroyIo (&Private->HttpIo); Private->HttpCreated = FALSE; } gBS->CloseProtocol ( Private->Controller, &gEfiCallerIdGuid, This->DriverBindingHandle, Private->ChildHandle ); gBS->UninstallMultipleProtocolInterfaces ( Private->ChildHandle, &gEfiLoadFileProtocolGuid, &Private->LoadFile, &gEfiDevicePathProtocolGuid, Private->DevicePath, NULL ); if (Private->DevicePath != NULL) { FreePool (Private->DevicePath); Private->DevicePath = NULL; } }
/** Disable the use of UEFI HTTP boot function. @param[in] Private The pointer to the driver's private data. @retval EFI_SUCCESS HTTP boot was successfully disabled. @retval EFI_NOT_STARTED The driver is already in stopped state. @retval EFI_INVALID_PARAMETER Private is NULL. @retval Others Unexpected error when stop the function. **/ EFI_STATUS HttpBootStop ( IN HTTP_BOOT_PRIVATE_DATA *Private ) { UINTN Index; if (Private == NULL) { return EFI_INVALID_PARAMETER; } if (!Private->Started) { return EFI_NOT_STARTED; } if (Private->HttpCreated) { HttpIoDestroyIo (&Private->HttpIo); Private->HttpCreated = FALSE; } Private->Started = FALSE; ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS)); Private->Port = 0; Private->BootFileUri = NULL; Private->BootFileUriParser = NULL; Private->BootFileSize = 0; Private->SelectIndex = 0; Private->SelectProxyType = HttpOfferTypeMax; if (!Private->UsingIpv6) { // // Stop and release the DHCP4 child. // Private->Dhcp4->Stop (Private->Dhcp4); Private->Dhcp4->Configure (Private->Dhcp4, NULL); for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) { if (Private->OfferBuffer[Index].Dhcp4.UriParser) { HttpUrlFreeParser (Private->OfferBuffer[Index].Dhcp4.UriParser); } } } else { // // Stop and release the DHCP6 child. // Private->Dhcp6->Stop (Private->Dhcp6); Private->Dhcp6->Configure (Private->Dhcp6, NULL); for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) { if (Private->OfferBuffer[Index].Dhcp6.UriParser) { HttpUrlFreeParser (Private->OfferBuffer[Index].Dhcp6.UriParser); } } } if (Private->FilePathUri!= NULL) { FreePool (Private->FilePathUri); HttpUrlFreeParser (Private->FilePathUriParser); Private->FilePathUri = NULL; Private->FilePathUriParser = NULL; } ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer)); Private->OfferNum = 0; ZeroMem (Private->OfferCount, sizeof (Private->OfferCount)); ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex)); HttpBootFreeCacheList (Private); return EFI_SUCCESS; }
/** Create a HTTP_IO to access the HTTP service. It will create and configure a HTTP child handle. @param[in] Image The handle of the driver image. @param[in] Controller The handle of the controller. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. @param[in] ConfigData The HTTP_IO configuration data. @param[in] Callback Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened. @param[in] Context The Context data which will be passed to the Callback function. @param[out] HttpIo The HTTP_IO. @retval EFI_SUCCESS The HTTP_IO is created and configured. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_UNSUPPORTED One or more of the control options are not supported in the implementation. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. @retval Others Failed to create the HTTP_IO or configure it. **/ EFI_STATUS HttpIoCreateIo ( IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN UINT8 IpVersion, IN HTTP_IO_CONFIG_DATA *ConfigData, IN HTTP_IO_CALLBACK Callback, IN VOID *Context, OUT HTTP_IO *HttpIo ) { EFI_STATUS Status; EFI_HTTP_CONFIG_DATA HttpConfigData; EFI_HTTPv4_ACCESS_POINT Http4AccessPoint; EFI_HTTPv6_ACCESS_POINT Http6AccessPoint; EFI_HTTP_PROTOCOL *Http; EFI_EVENT Event; if ((Image == NULL) || (Controller == NULL) || (ConfigData == NULL) || (HttpIo == NULL)) { return EFI_INVALID_PARAMETER; } if (IpVersion != IP_VERSION_4 && IpVersion != IP_VERSION_6) { return EFI_UNSUPPORTED; } ZeroMem (HttpIo, sizeof (HTTP_IO)); // // Create the HTTP child instance and get the HTTP protocol. // Status = NetLibCreateServiceChild ( Controller, Image, &gEfiHttpServiceBindingProtocolGuid, &HttpIo->Handle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->OpenProtocol ( HttpIo->Handle, &gEfiHttpProtocolGuid, (VOID **) &Http, Image, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status) || (Http == NULL)) { goto ON_ERROR; } // // Init the configuration data and configure the HTTP child. // HttpIo->Image = Image; HttpIo->Controller = Controller; HttpIo->IpVersion = IpVersion; HttpIo->Http = Http; HttpIo->Callback = Callback; HttpIo->Context = Context; ZeroMem (&HttpConfigData, sizeof (EFI_HTTP_CONFIG_DATA)); HttpConfigData.HttpVersion = HttpVersion11; HttpConfigData.TimeOutMillisec = ConfigData->Config4.RequestTimeOut; if (HttpIo->IpVersion == IP_VERSION_4) { HttpConfigData.LocalAddressIsIPv6 = FALSE; Http4AccessPoint.UseDefaultAddress = ConfigData->Config4.UseDefaultAddress; Http4AccessPoint.LocalPort = ConfigData->Config4.LocalPort; IP4_COPY_ADDRESS (&Http4AccessPoint.LocalAddress, &ConfigData->Config4.LocalIp); IP4_COPY_ADDRESS (&Http4AccessPoint.LocalSubnet, &ConfigData->Config4.SubnetMask); HttpConfigData.AccessPoint.IPv4Node = &Http4AccessPoint; } else { HttpConfigData.LocalAddressIsIPv6 = TRUE; Http6AccessPoint.LocalPort = ConfigData->Config6.LocalPort; IP6_COPY_ADDRESS (&Http6AccessPoint.LocalAddress, &ConfigData->Config6.LocalIp); HttpConfigData.AccessPoint.IPv6Node = &Http6AccessPoint; } Status = Http->Configure (Http, &HttpConfigData); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Create events for variuos asynchronous operations. // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, HttpIoNotify, &HttpIo->IsTxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->ReqToken.Event = Event; HttpIo->ReqToken.Message = &HttpIo->ReqMessage; Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, HttpIoNotify, &HttpIo->IsRxDone, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->RspToken.Event = Event; HttpIo->RspToken.Message = &HttpIo->RspMessage; // // Create TimeoutEvent for response // Status = gBS->CreateEvent ( EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Event ); if (EFI_ERROR (Status)) { goto ON_ERROR; } HttpIo->TimeoutEvent = Event; return EFI_SUCCESS; ON_ERROR: HttpIoDestroyIo (HttpIo); return Status; }