+/** @file\r
+ Load the deferred images after user is identified.\r
+ \r
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UserIdentifyManager.h"\r
+\r
+EFI_HANDLE mDeferredImageHandle;\r
+\r
+/**\r
+ The function will load all the deferred images again. If the deferred image is loaded\r
+ successfully, try to start it.\r
+\r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+LoadDeferredImage (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuf;\r
+ UINTN Index;\r
+ UINTN DriverIndex;\r
+ EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;\r
+ VOID *DriverImage;\r
+ UINTN ImageSize; \r
+ BOOLEAN BootOption;\r
+ EFI_HANDLE ImageHandle;\r
+ UINTN ExitDataSize;\r
+ CHAR16 *ExitData;\r
+\r
+ //\r
+ // Find all the deferred image load protocols.\r
+ //\r
+ HandleCount = 0;\r
+ HandleBuf = NULL;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiDeferredImageLoadProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuf\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuf[Index],\r
+ &gEfiDeferredImageLoadProtocolGuid,\r
+ (VOID **) &DeferredImage\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue ;\r
+ }\r
+\r
+ DriverIndex = 0;\r
+ do {\r
+ //\r
+ // Load all the deferred images in this protocol instance.\r
+ //\r
+ Status = DeferredImage->GetImageInfo(\r
+ DeferredImage, \r
+ DriverIndex, \r
+ &ImageDevicePath, \r
+ (VOID **) &DriverImage,\r
+ &ImageSize, \r
+ &BootOption\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ } \r
+\r
+ //\r
+ // Load and start the image.\r
+ //\r
+ Status = gBS->LoadImage (\r
+ BootOption,\r
+ mDeferredImageHandle,\r
+ ImageDevicePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Before calling the image, enable the Watchdog Timer for\r
+ // a 5 Minute period\r
+ //\r
+ gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
+ Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);\r
+ \r
+ //\r
+ // Clear the Watchdog Timer after the image returns.\r
+ //\r
+ gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
+ }\r
+ DriverIndex++;\r
+ } while (TRUE);\r
+ }\r
+ FreePool (HandleBuf); \r
+}\r
+\r
+\r
+/**\r
+ Register an event notification function for user profile changed.\r
+\r
+ @param[in] ImageHandle Image handle this driver.\r
+\r
+**/\r
+VOID\r
+LoadDeferredImageInit (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_EVENT Event;\r
+\r
+ mDeferredImageHandle = ImageHandle;\r
+ \r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ LoadDeferredImage,\r
+ NULL,\r
+ &gEfiEventUserProfileChangedGuid,\r
+ &Event\r
+ );\r
+\r
+ ASSERT (Status == EFI_SUCCESS);\r
+}\r