2 Implement defer image load services for user identification in UEFI2.2.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "DxeDeferImageLoadLib.h"
12 // Handle for the Deferred Image Load Protocol instance produced by this driver.
14 EFI_HANDLE mDeferredImageHandle
= NULL
;
15 BOOLEAN mIsProtocolInstalled
= FALSE
;
16 EFI_USER_MANAGER_PROTOCOL
*mUserManager
= NULL
;
17 DEFERRED_IMAGE_TABLE mDeferredImage
= {
18 0, // Deferred image count
19 NULL
// The deferred image info
22 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL gDeferredImageLoad
= {
29 @param[in] File This is a pointer to the device path of the file
30 that is being dispatched.
32 @return UINT32 Image Type
37 IN CONST EFI_DEVICE_PATH_PROTOCOL
*File
41 EFI_HANDLE DeviceHandle
;
42 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
43 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
46 // First check to see if File is from a Firmware Volume
49 TempDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)File
;
50 Status
= gBS
->LocateDevicePath (
51 &gEfiFirmwareVolume2ProtocolGuid
,
55 if (!EFI_ERROR (Status
)) {
56 Status
= gBS
->OpenProtocol (
58 &gEfiFirmwareVolume2ProtocolGuid
,
62 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
64 if (!EFI_ERROR (Status
)) {
70 // Next check to see if File is from a Block I/O device
73 TempDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)File
;
74 Status
= gBS
->LocateDevicePath (
75 &gEfiBlockIoProtocolGuid
,
79 if (!EFI_ERROR (Status
)) {
81 Status
= gBS
->OpenProtocol (
83 &gEfiBlockIoProtocolGuid
,
87 EFI_OPEN_PROTOCOL_GET_PROTOCOL
89 if (!EFI_ERROR (Status
) && BlockIo
!= NULL
) {
90 if (BlockIo
->Media
!= NULL
) {
91 if (BlockIo
->Media
->RemovableMedia
) {
93 // Block I/O is present and specifies the media is removable
95 return IMAGE_FROM_REMOVABLE_MEDIA
;
98 // Block I/O is present and specifies the media is not removable
100 return IMAGE_FROM_FIXED_MEDIA
;
107 // File is not in a Firmware Volume or on a Block I/O device, so check to see if
108 // the device path supports the Simple File System Protocol.
111 TempDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)File
;
112 Status
= gBS
->LocateDevicePath (
113 &gEfiSimpleFileSystemProtocolGuid
,
117 if (!EFI_ERROR (Status
)) {
119 // Simple File System is present without Block I/O, so assume media is fixed.
121 return IMAGE_FROM_FIXED_MEDIA
;
125 // File is not from an FV, Block I/O or Simple File System, so the only options
126 // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.
128 TempDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)File
;
129 while (!IsDevicePathEndType (TempDevicePath
)) {
130 switch (DevicePathType (TempDevicePath
)) {
132 case MEDIA_DEVICE_PATH
:
133 if (DevicePathSubType (TempDevicePath
) == MEDIA_RELATIVE_OFFSET_RANGE_DP
) {
134 return IMAGE_FROM_OPTION_ROM
;
138 case MESSAGING_DEVICE_PATH
:
139 if (DevicePathSubType(TempDevicePath
) == MSG_MAC_ADDR_DP
) {
140 return IMAGE_FROM_REMOVABLE_MEDIA
;
147 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
149 return IMAGE_UNKNOWN
;
154 Get current user's access right.
156 @param[out] AccessControl Points to the user's access control data, the
157 caller should free data buffer.
158 @param[in] AccessType The type of user access control.
160 @retval EFI_SUCCESS Get current user access control successfully
161 @retval others Fail to get current user access control
166 OUT EFI_USER_INFO_ACCESS_CONTROL
**AccessControl
,
171 EFI_USER_INFO_HANDLE UserInfo
;
174 EFI_USER_INFO_ACCESS_CONTROL
*Access
;
175 EFI_USER_PROFILE_HANDLE CurrentUser
;
177 EFI_USER_MANAGER_PROTOCOL
*UserManager
;
180 Status
= gBS
->LocateProtocol (
181 &gEfiUserManagerProtocolGuid
,
183 (VOID
**) &UserManager
185 if (EFI_ERROR (Status
)) {
186 return EFI_NOT_FOUND
;
190 // Get current user access information.
192 UserManager
->Current (UserManager
, &CurrentUser
);
199 // Get next user information.
201 Status
= UserManager
->GetNextInfo (UserManager
, CurrentUser
, &UserInfo
);
202 if (EFI_ERROR (Status
)) {
206 Status
= UserManager
->GetInfo (
213 if (Status
== EFI_BUFFER_TOO_SMALL
) {
217 Info
= AllocateZeroPool (InfoSize
);
218 ASSERT (Info
!= NULL
);
219 Status
= UserManager
->GetInfo (
228 if (EFI_ERROR (Status
)) {
232 ASSERT (Info
!= NULL
);
233 if (Info
->InfoType
!= EFI_USER_INFO_ACCESS_POLICY_RECORD
) {
238 // Get specified access information.
241 while (CheckLen
< Info
->InfoSize
- sizeof (EFI_USER_INFO
)) {
242 Access
= (EFI_USER_INFO_ACCESS_CONTROL
*) ((UINT8
*) (Info
+ 1) + CheckLen
);
243 if (Access
->Type
== AccessType
) {
244 *AccessControl
= AllocateZeroPool (Access
->Size
);
245 ASSERT (*AccessControl
!= NULL
);
246 CopyMem (*AccessControl
, Access
, Access
->Size
);
250 CheckLen
+= Access
->Size
;
257 return EFI_NOT_FOUND
;
261 Get file name from device path.
263 The file name may contain one or more device path node. Save the file name in a
264 buffer if file name is found. The caller is responsible to free the buffer.
266 @param[in] DevicePath A pointer to a device path.
267 @param[out] FileName The callee allocated buffer to save the file name if file name is found.
268 @param[out] FileNameOffset The offset of file name in device path if file name is found.
270 @retval UINTN The file name length. 0 means file name is not found.
275 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
276 OUT UINT8
**FileName
,
277 OUT UINTN
*FileNameOffset
281 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
282 EFI_DEVICE_PATH_PROTOCOL
*RootDevicePath
;
286 CHAR16 FirstNodeChar
;
289 // Get the length of DevicePath before file name.
292 RootDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)DevicePath
;
293 while (!IsDevicePathEnd (RootDevicePath
)) {
294 if ((DevicePathType(RootDevicePath
) == MEDIA_DEVICE_PATH
) && (DevicePathSubType(RootDevicePath
) == MEDIA_FILEPATH_DP
)) {
297 Length
+= DevicePathNodeLength (RootDevicePath
);
298 RootDevicePath
= NextDevicePathNode (RootDevicePath
);
301 *FileNameOffset
= Length
;
307 // Get the file name length.
310 TmpDevicePath
= RootDevicePath
;
311 while (!IsDevicePathEnd (TmpDevicePath
)) {
312 if ((DevicePathType(TmpDevicePath
) != MEDIA_DEVICE_PATH
) || (DevicePathSubType(TmpDevicePath
) != MEDIA_FILEPATH_DP
)) {
315 Length
+= DevicePathNodeLength (TmpDevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
);
316 TmpDevicePath
= NextDevicePathNode (TmpDevicePath
);
322 *FileName
= AllocateZeroPool (Length
);
323 ASSERT (*FileName
!= NULL
);
326 // Copy the file name to the buffer.
330 TmpDevicePath
= RootDevicePath
;
331 while (!IsDevicePathEnd (TmpDevicePath
)) {
332 if ((DevicePathType(TmpDevicePath
) != MEDIA_DEVICE_PATH
) || (DevicePathSubType(TmpDevicePath
) != MEDIA_FILEPATH_DP
)) {
336 FirstNodeChar
= (CHAR16
) ReadUnaligned16 ((UINT16
*)((UINT8
*)TmpDevicePath
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
)));
337 NodeStr
= (CHAR8
*)TmpDevicePath
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
);
338 NodeStrLength
= DevicePathNodeLength (TmpDevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
) - sizeof(CHAR16
);
340 if ((FirstNodeChar
== '\\') && (LastNodeChar
== '\\')) {
342 // Skip separator "\" when there are two separators.
344 NodeStr
+= sizeof (CHAR16
);
345 NodeStrLength
-= sizeof (CHAR16
);
346 } else if ((FirstNodeChar
!= '\\') && (LastNodeChar
!= '\\')) {
348 // Add separator "\" when there is no separator.
350 WriteUnaligned16 ((UINT16
*)(*FileName
+ Length
), '\\');
351 Length
+= sizeof (CHAR16
);
353 CopyMem (*FileName
+ Length
, NodeStr
, NodeStrLength
);
354 Length
+= NodeStrLength
;
356 LastNodeChar
= (CHAR16
) ReadUnaligned16 ((UINT16
*) (NodeStr
+ NodeStrLength
- sizeof(CHAR16
)));
357 TmpDevicePath
= NextDevicePathNode (TmpDevicePath
);
365 Check whether the DevicePath2 is identical with DevicePath1, or identical with
366 DevicePath1's child device path.
368 If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device
369 path, then TRUE returned. Otherwise, FALSE is returned.
371 If DevicePath1 is NULL, then ASSERT().
372 If DevicePath2 is NULL, then ASSERT().
374 @param[in] DevicePath1 A pointer to a device path.
375 @param[in] DevicePath2 A pointer to a device path.
377 @retval TRUE Two device paths are identical , or DevicePath2 is
378 DevicePath1's child device path.
379 @retval FALSE Two device paths are not identical, and DevicePath2
380 is not DevicePath1's child device path.
385 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath1
,
386 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath2
389 UINTN DevicePathSize
;
394 UINTN FileNameOffset1
;
395 UINTN FileNameOffset2
;
396 BOOLEAN DevicePathEqual
;
400 DevicePathEqual
= TRUE
;
402 ASSERT (DevicePath1
!= NULL
);
403 ASSERT (DevicePath2
!= NULL
);
404 if (IsDevicePathEnd (DevicePath1
)) {
409 // The file name may contain one or more device path node.
410 // To compare the file name, copy file name to a buffer and compare the buffer.
412 FileNameSize1
= GetFileName (DevicePath1
, &FileName1
, &FileNameOffset1
);
413 if (FileNameSize1
!= 0) {
414 FileNameSize2
= GetFileName (DevicePath2
, &FileName2
, &FileNameOffset2
);
415 if (FileNameOffset1
!= FileNameOffset2
) {
416 DevicePathEqual
= FALSE
;
419 if (CompareMem (DevicePath1
, DevicePath2
, FileNameOffset1
) != 0) {
420 DevicePathEqual
= FALSE
;
423 if (FileNameSize1
> FileNameSize2
) {
424 DevicePathEqual
= FALSE
;
427 if (CompareMem (FileName1
, FileName2
, FileNameSize1
) != 0) {
428 DevicePathEqual
= FALSE
;
431 DevicePathEqual
= TRUE
;
435 DevicePathSize
= GetDevicePathSize (DevicePath1
);
436 if (DevicePathSize
> GetDevicePathSize (DevicePath2
)) {
441 // Exclude the end of device path node.
443 DevicePathSize
-= sizeof (EFI_DEVICE_PATH_PROTOCOL
);
444 if (CompareMem (DevicePath1
, DevicePath2
, DevicePathSize
) != 0) {
445 DevicePathEqual
= FALSE
;
449 if (FileName1
!= NULL
) {
450 FreePool (FileName1
);
452 if (FileName2
!= NULL
) {
453 FreePool (FileName2
);
455 return DevicePathEqual
;
460 Check whether the image pointed to by DevicePath is in the device path list
461 specified by AccessType.
463 @param[in] DevicePath Points to device path.
464 @param[in] AccessType The type of user access control.
466 @retval TRUE The DevicePath is in the specified List.
467 @retval FALSE The DevicePath is not in the specified List.
472 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
477 EFI_USER_INFO_ACCESS_CONTROL
*Access
;
478 EFI_DEVICE_PATH_PROTOCOL
*Path
;
481 Status
= GetAccessControl (&Access
, AccessType
);
482 if (EFI_ERROR (Status
)) {
487 while (OffSet
< Access
->Size
- sizeof (EFI_USER_INFO_ACCESS_CONTROL
)) {
488 Path
= (EFI_DEVICE_PATH_PROTOCOL
*)((UINT8
*)(Access
+ 1) + OffSet
);
489 if (CheckDevicePath (Path
, DevicePath
)) {
491 // The device path is found in list.
496 OffSet
+= GetDevicePathSize (Path
);
505 Check whether the image pointed to by DevicePath is permitted to load.
507 @param[in] DevicePath Points to device path
509 @retval TRUE The image pointed by DevicePath is permitted to load.
510 @retval FALSE The image pointed by DevicePath is forbidden to load.
515 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
518 if (IsDevicePathInList (DevicePath
, EFI_USER_INFO_ACCESS_PERMIT_LOAD
)) {
520 // This access control overrides any restrictions put in place by the
521 // EFI_USER_INFO_ACCESS_FORBID_LOAD record.
526 if (IsDevicePathInList (DevicePath
, EFI_USER_INFO_ACCESS_FORBID_LOAD
)) {
528 // The device path is found in the forbidden list.
538 Check the image pointed by DevicePath is a boot option or not.
540 @param[in] DevicePath Points to device path.
542 @retval TRUE The image pointed by DevicePath is a boot option.
543 @retval FALSE The image pointed by DevicePath is not a boot option.
548 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
552 UINT16
*BootOrderList
;
553 UINTN BootOrderListSize
;
558 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
563 BootOrderListSize
= 0;
564 BootOrderList
= NULL
;
565 Status
= gRT
->GetVariable (
567 &gEfiGlobalVariableGuid
,
572 if (Status
== EFI_BUFFER_TOO_SMALL
) {
573 BootOrderList
= AllocateZeroPool (BootOrderListSize
);
574 ASSERT (BootOrderList
!= NULL
);
575 Status
= gRT
->GetVariable (
577 &gEfiGlobalVariableGuid
,
584 if (EFI_ERROR (Status
)) {
592 for (Index
= 0; Index
< BootOrderListSize
/ sizeof (UINT16
); Index
++) {
594 // Try to find the DevicePath in BootOption
596 UnicodeSPrint (StrTemp
, sizeof (StrTemp
), L
"Boot%04x", Index
);
597 GetEfiGlobalVariable2 (StrTemp
, (VOID
**)&OptionBuffer
, NULL
);
598 if (OptionBuffer
== NULL
) {
603 // Check whether the image is forbidden.
606 OptionPtr
= OptionBuffer
;
610 OptionPtr
+= sizeof (UINT32
);
613 // Skip device path length.
615 OptionPtr
+= sizeof (UINT16
);
618 // Skip descript string
620 OptionPtr
+= StrSize ((UINT16
*) OptionPtr
);
623 // Now OptionPtr points to Device Path.
625 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) OptionPtr
;
627 if (CheckDevicePath (DevicePath
, OptionDevicePath
)) {
628 FreePool (OptionBuffer
);
632 FreePool (OptionBuffer
);
636 if (BootOrderList
!= NULL
) {
637 FreePool (BootOrderList
);
645 Add the image info to a deferred image list.
647 @param[in] ImageDevicePath A pointer to the device path of a image.
648 @param[in] Image Points to the first byte of the image, or NULL if the
649 image is not available.
650 @param[in] ImageSize The size of the image, or 0 if the image is not available.
654 PutDefferedImageInfo (
655 IN CONST EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
,
660 DEFERRED_IMAGE_INFO
*CurImageInfo
;
664 // Expand memory for the new deferred image.
666 if (mDeferredImage
.Count
== 0) {
667 mDeferredImage
.ImageInfo
= AllocatePool (sizeof (DEFERRED_IMAGE_INFO
));
668 ASSERT (mDeferredImage
.ImageInfo
!= NULL
);
670 CurImageInfo
= AllocatePool ((mDeferredImage
.Count
+ 1) * sizeof (DEFERRED_IMAGE_INFO
));
671 ASSERT (CurImageInfo
!= NULL
);
675 mDeferredImage
.ImageInfo
,
676 mDeferredImage
.Count
* sizeof (DEFERRED_IMAGE_INFO
)
678 FreePool (mDeferredImage
.ImageInfo
);
679 mDeferredImage
.ImageInfo
= CurImageInfo
;
681 mDeferredImage
.Count
++;
684 // Save the deferred image information.
686 CurImageInfo
= &mDeferredImage
.ImageInfo
[mDeferredImage
.Count
- 1];
687 PathSize
= GetDevicePathSize (ImageDevicePath
);
688 CurImageInfo
->ImageDevicePath
= AllocateZeroPool (PathSize
);
689 ASSERT (CurImageInfo
->ImageDevicePath
!= NULL
);
690 CopyMem (CurImageInfo
->ImageDevicePath
, ImageDevicePath
, PathSize
);
692 CurImageInfo
->Image
= Image
;
693 CurImageInfo
->ImageSize
= ImageSize
;
694 CurImageInfo
->BootOption
= IsBootOption (ImageDevicePath
);
699 Returns information about a deferred image.
701 This function returns information about a single deferred image. The deferred images are
702 numbered consecutively, starting with 0. If there is no image which corresponds to
703 ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by
704 iteratively calling this function until EFI_NOT_FOUND is returned.
705 Image may be NULL and ImageSize set to 0 if the decision to defer execution was made
706 because of the location of the executable image, rather than its actual contents.
708 @param[in] This Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.
709 @param[in] ImageIndex Zero-based index of the deferred index.
710 @param[out] ImageDevicePath On return, points to a pointer to the device path of the image.
711 The device path should not be freed by the caller.
712 @param[out] Image On return, points to the first byte of the image or NULL if the
713 image is not available. The image should not be freed by the caller
714 unless LoadImage() has been successfully called.
715 @param[out] ImageSize On return, the size of the image, or 0 if the image is not available.
716 @param[out] BootOption On return, points to TRUE if the image was intended as a boot option
717 or FALSE if it was not intended as a boot option.
719 @retval EFI_SUCCESS Image information returned successfully.
720 @retval EFI_NOT_FOUND ImageIndex does not refer to a valid image.
721 @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or
727 GetDefferedImageInfo (
728 IN EFI_DEFERRED_IMAGE_LOAD_PROTOCOL
*This
,
730 OUT EFI_DEVICE_PATH_PROTOCOL
**ImageDevicePath
,
732 OUT UINTN
*ImageSize
,
733 OUT BOOLEAN
*BootOption
736 DEFERRED_IMAGE_INFO
*ReqImageInfo
;
739 // Check the parameter.
742 if ((This
== NULL
) || (ImageSize
== NULL
) || (Image
== NULL
)) {
743 return EFI_INVALID_PARAMETER
;
746 if ((ImageDevicePath
== NULL
) || (BootOption
== NULL
)) {
747 return EFI_INVALID_PARAMETER
;
750 if (ImageIndex
>= mDeferredImage
.Count
) {
751 return EFI_NOT_FOUND
;
755 // Get the request deferred image.
757 ReqImageInfo
= &mDeferredImage
.ImageInfo
[ImageIndex
];
759 *ImageDevicePath
= ReqImageInfo
->ImageDevicePath
;
760 *Image
= ReqImageInfo
->Image
;
761 *ImageSize
= ReqImageInfo
->ImageSize
;
762 *BootOption
= ReqImageInfo
->BootOption
;
769 Provides the service of deferring image load based on platform policy control,
770 and installs Deferred Image Load Protocol.
772 @param[in] AuthenticationStatus This is the authentication status returned from the
773 security measurement services for the input file.
774 @param[in] File This is a pointer to the device path of the file that
775 is being dispatched. This will optionally be used for
777 @param[in] FileBuffer File buffer matches the input file device path.
778 @param[in] FileSize Size of File buffer matches the input file device path.
779 @param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.
781 @retval EFI_SUCCESS FileBuffer is NULL and current user has permission to start
782 UEFI device drivers on the device path specified by DevicePath.
783 @retval EFI_SUCCESS The file specified by DevicePath and non-NULL
784 FileBuffer did authenticate, and the platform policy dictates
785 that the DXE Foundation may use the file.
786 @retval EFI_SECURITY_VIOLATION FileBuffer is NULL and the user has no
787 permission to start UEFI device drivers on the device path specified
789 @retval EFI_SECURITY_VIOLATION FileBuffer is not NULL and the user has no permission to load
790 drivers from the device path specified by DevicePath. The
791 image has been added into the list of the deferred images.
792 @retval EFI_ACCESS_DENIED The file specified by File and FileBuffer did not
793 authenticate, and the platform policy dictates that the DXE
794 Foundation many not use File.
799 DxeDeferImageLoadHandler (
800 IN UINT32 AuthenticationStatus
,
801 IN CONST EFI_DEVICE_PATH_PROTOCOL
*File
,
804 IN BOOLEAN BootPolicy
808 EFI_USER_PROFILE_HANDLE CurrentUser
;
813 // Ignore if File is NULL.
820 // Check whether user has a logon.
823 if (mUserManager
!= NULL
) {
824 mUserManager
->Current (mUserManager
, &CurrentUser
);
825 if (CurrentUser
!= NULL
) {
827 // The user is logon; verify the FilePath by current user access policy.
829 if (!VerifyDevicePath (File
)) {
830 DEBUG ((EFI_D_ERROR
, "[Security] The image is forbidden to load!\n"));
831 return EFI_SECURITY_VIOLATION
;
838 // Still no user logon.
839 // Check the file type and get policy setting.
841 FileType
= GetFileType (File
);
842 Policy
= PcdGet32 (PcdDeferImageLoadPolicy
);
843 if ((Policy
& FileType
) == FileType
) {
845 // This file type is secure to load.
850 DEBUG ((EFI_D_INFO
, "[Security] No user identified, the image is deferred to load!\n"));
851 PutDefferedImageInfo (File
, FileBuffer
, FileSize
);
854 // Install the Deferred Image Load Protocol onto a new handle.
856 if (!mIsProtocolInstalled
) {
857 Status
= gBS
->InstallMultipleProtocolInterfaces (
858 &mDeferredImageHandle
,
859 &gEfiDeferredImageLoadProtocolGuid
,
863 ASSERT_EFI_ERROR (Status
);
864 mIsProtocolInstalled
= TRUE
;
867 return EFI_ACCESS_DENIED
;
871 Locate user manager protocol when user manager is installed.
873 @param[in] Event The Event that is being processed, not used.
874 @param[in] Context Event Context, not used.
879 FindUserManagerProtocol (
884 gBS
->LocateProtocol (
885 &gEfiUserManagerProtocolGuid
,
887 (VOID
**) &mUserManager
894 Register security handler for deferred image load.
896 @param[in] ImageHandle ImageHandle of the loaded driver.
897 @param[in] SystemTable Pointer to the EFI System Table.
899 @retval EFI_SUCCESS The handlers were registered successfully.
903 DxeDeferImageLoadLibConstructor (
904 IN EFI_HANDLE ImageHandle
,
905 IN EFI_SYSTEM_TABLE
*SystemTable
911 // Register user manager notification function.
913 EfiCreateProtocolNotifyEvent (
914 &gEfiUserManagerProtocolGuid
,
916 FindUserManagerProtocol
,
921 return RegisterSecurity2Handler (
922 DxeDeferImageLoadHandler
,
923 EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD