1 /** @file
2   Load the deferred images after user is identified.
3 
4 Copyright (c) 2009 - 2010, 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 "UserIdentifyManager.h"
16 
17 EFI_HANDLE        mDeferredImageHandle;
18 
19 /**
20   The function will load all the deferred images again. If the deferred image is loaded
21   successfully, try to start it.
22 
23   @param  Event         Event whose notification function is being invoked.
24   @param  Context       Pointer to the notification function's context
25 
26 **/
27 VOID
28 EFIAPI
LoadDeferredImage(IN EFI_EVENT Event,IN VOID * Context)29 LoadDeferredImage (
30   IN EFI_EVENT                       Event,
31   IN VOID                            *Context
32   )
33 {
34   EFI_STATUS                         Status;
35   EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;
36   UINTN                              HandleCount;
37   EFI_HANDLE                         *HandleBuf;
38   UINTN                              Index;
39   UINTN                              DriverIndex;
40   EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;
41   VOID                               *DriverImage;
42   UINTN                              ImageSize;
43   BOOLEAN                            BootOption;
44   EFI_HANDLE                         ImageHandle;
45   UINTN                              ExitDataSize;
46   CHAR16                             *ExitData;
47 
48   //
49   // Find all the deferred image load protocols.
50   //
51   HandleCount = 0;
52   HandleBuf   = NULL;
53   Status = gBS->LocateHandleBuffer (
54                   ByProtocol,
55                   &gEfiDeferredImageLoadProtocolGuid,
56                   NULL,
57                   &HandleCount,
58                   &HandleBuf
59                   );
60   if (EFI_ERROR (Status)) {
61     return ;
62   }
63 
64   for (Index = 0; Index < HandleCount; Index++) {
65     Status = gBS->HandleProtocol (
66                     HandleBuf[Index],
67                     &gEfiDeferredImageLoadProtocolGuid,
68                     (VOID **) &DeferredImage
69                     );
70     if (EFI_ERROR (Status)) {
71       continue ;
72     }
73 
74     DriverIndex = 0;
75     do {
76       //
77       // Load all the deferred images in this protocol instance.
78       //
79       Status = DeferredImage->GetImageInfo(
80                                 DeferredImage,
81                                 DriverIndex,
82                                 &ImageDevicePath,
83                                 (VOID **) &DriverImage,
84                                 &ImageSize,
85                                 &BootOption
86                                 );
87       if (EFI_ERROR (Status)) {
88         break;
89       }
90 
91       //
92       // Load and start the image.
93       //
94       Status = gBS->LoadImage (
95                       BootOption,
96                       mDeferredImageHandle,
97                       ImageDevicePath,
98                       NULL,
99                       0,
100                       &ImageHandle
101                       );
102       if (!EFI_ERROR (Status)) {
103         //
104         // Before calling the image, enable the Watchdog Timer for
105         // a 5 Minute period
106         //
107         gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
108         Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
109 
110         //
111         // Clear the Watchdog Timer after the image returns.
112         //
113         gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
114       }
115       DriverIndex++;
116     } while (TRUE);
117   }
118   FreePool (HandleBuf);
119 }
120 
121 
122 /**
123   Register an event notification function for user profile changed.
124 
125   @param[in]  ImageHandle     Image handle this driver.
126 
127 **/
128 VOID
LoadDeferredImageInit(IN EFI_HANDLE ImageHandle)129 LoadDeferredImageInit (
130   IN EFI_HANDLE        ImageHandle
131   )
132 {
133   EFI_STATUS    Status;
134   EFI_EVENT     Event;
135 
136   mDeferredImageHandle = ImageHandle;
137 
138   Status = gBS->CreateEventEx (
139                   EVT_NOTIFY_SIGNAL,
140                   TPL_CALLBACK,
141                   LoadDeferredImage,
142                   NULL,
143                   &gEfiEventUserProfileChangedGuid,
144                   &Event
145                   );
146 
147   ASSERT (Status == EFI_SUCCESS);
148 }
149