1 /** @file
2   The functions to modify a user profile.
3 
4 Copyright (c) 2009 - 2015, 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 "UserProfileManager.h"
16 
17 EFI_USER_PROFILE_HANDLE           mModifyUser = NULL;
18 
19 /**
20   Display user select form, cab select a user to modify.
21 
22 **/
23 VOID
SelectUserToModify(VOID)24 SelectUserToModify  (
25   VOID
26   )
27 {
28   EFI_STATUS              Status;
29   UINT8                   Index;
30   EFI_USER_PROFILE_HANDLE User;
31   EFI_USER_PROFILE_HANDLE CurrentUser;
32   UINT32                  CurrentAccessRight;
33   VOID                    *StartOpCodeHandle;
34   VOID                    *EndOpCodeHandle;
35   EFI_IFR_GUID_LABEL      *StartLabel;
36   EFI_IFR_GUID_LABEL      *EndLabel;
37 
38   //
39   // Initialize the container for dynamic opcodes.
40   //
41   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
42   ASSERT (StartOpCodeHandle != NULL);
43 
44   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
45   ASSERT (EndOpCodeHandle != NULL);
46 
47   //
48   // Create Hii Extend Label OpCode.
49   //
50   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
51                                         StartOpCodeHandle,
52                                         &gEfiIfrTianoGuid,
53                                         NULL,
54                                         sizeof (EFI_IFR_GUID_LABEL)
55                                         );
56   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
57   StartLabel->Number        = LABEL_USER_MOD_FUNC;
58 
59   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
60                                       EndOpCodeHandle,
61                                       &gEfiIfrTianoGuid,
62                                       NULL,
63                                       sizeof (EFI_IFR_GUID_LABEL)
64                                       );
65   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
66   EndLabel->Number        = LABEL_END;
67 
68   //
69   // Add each user can be modified.
70   //
71   User  = NULL;
72   Index = 1;
73   mUserManager->Current (mUserManager, &CurrentUser);
74   while (TRUE) {
75     Status = mUserManager->GetNext (mUserManager, &User);
76     if (EFI_ERROR (Status)) {
77       break;
78     }
79 
80     Status = GetAccessRight (&CurrentAccessRight);
81     if (EFI_ERROR (Status)) {
82       CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
83     }
84 
85     if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || (User == CurrentUser)) {
86       AddUserToForm (User, (UINT16)(KEY_MODIFY_USER | KEY_SELECT_USER | Index), StartOpCodeHandle);
87     }
88     Index++;
89   }
90 
91   HiiUpdateForm (
92     mCallbackInfo->HiiHandle, // HII handle
93     &gUserProfileManagerGuid, // Formset GUID
94     FORMID_MODIFY_USER,       // Form ID
95     StartOpCodeHandle,        // Label for where to insert opcodes
96     EndOpCodeHandle           // Replace data
97     );
98 
99   HiiFreeOpCodeHandle (StartOpCodeHandle);
100   HiiFreeOpCodeHandle (EndOpCodeHandle);
101 }
102 
103 
104 /**
105   Get all the user info from mModifyUser in the user manager, and save on the
106   global variable.
107 
108 **/
109 VOID
GetAllUserInfo(VOID)110 GetAllUserInfo (
111   VOID
112   )
113 {
114   EFI_STATUS            Status;
115   EFI_USER_INFO_HANDLE  UserInfo;
116   EFI_USER_INFO         *Info;
117   UINTN                 InfoSize;
118   UINTN                 MemSize;
119   UINTN                 DataLen;
120 
121   //
122   // Init variable to default value.
123   //
124   mProviderChoice                   = 0;
125   mConncetLogical                   = 0;
126 
127   mUserInfo.CreateDateExist         = FALSE;
128   mUserInfo.UsageDateExist          = FALSE;
129   mUserInfo.UsageCount              = 0;
130 
131   mUserInfo.AccessPolicyLen         = 0;
132   mUserInfo.AccessPolicyModified    = FALSE;
133   if (mUserInfo.AccessPolicy != NULL) {
134     FreePool (mUserInfo.AccessPolicy);
135     mUserInfo.AccessPolicy = NULL;
136   }
137   mUserInfo.IdentityPolicyLen       = 0;
138   mUserInfo.IdentityPolicyModified  = FALSE;
139   if (mUserInfo.IdentityPolicy != NULL) {
140     FreePool (mUserInfo.IdentityPolicy);
141     mUserInfo.IdentityPolicy = NULL;
142   }
143 
144   //
145   // Allocate user information memory.
146   //
147   MemSize = sizeof (EFI_USER_INFO) + 63;
148   Info    = AllocateZeroPool (MemSize);
149   if (Info == NULL) {
150     return ;
151   }
152 
153   //
154   // Get each user information.
155   //
156   UserInfo = NULL;
157   while (TRUE) {
158     Status = mUserManager->GetNextInfo (mUserManager, mModifyUser, &UserInfo);
159     if (EFI_ERROR (Status)) {
160       break;
161     }
162     //
163     // Get information.
164     //
165     InfoSize  = MemSize;
166     Status    = mUserManager->GetInfo (
167                                 mUserManager,
168                                 mModifyUser,
169                                 UserInfo,
170                                 Info,
171                                 &InfoSize
172                                 );
173     if (Status == EFI_BUFFER_TOO_SMALL) {
174       MemSize = InfoSize;
175       FreePool (Info);
176       Info = AllocateZeroPool (MemSize);
177       if (Info == NULL) {
178         return ;
179       }
180 
181       Status = mUserManager->GetInfo (
182                                mUserManager,
183                                mModifyUser,
184                                UserInfo,
185                                Info,
186                                &InfoSize
187                                );
188     }
189 
190     if (Status == EFI_SUCCESS) {
191       //
192       // Deal with each information according to informaiton type.
193       //
194       DataLen = Info->InfoSize - sizeof (EFI_USER_INFO);
195       switch (Info->InfoType) {
196       case EFI_USER_INFO_NAME_RECORD:
197         CopyMem (&mUserInfo.UserName, (UINT8 *) (Info + 1), DataLen);
198         break;
199 
200       case EFI_USER_INFO_CREATE_DATE_RECORD:
201         CopyMem (&mUserInfo.CreateDate, (UINT8 *) (Info + 1), DataLen);
202         mUserInfo.CreateDateExist = TRUE;
203         break;
204 
205       case EFI_USER_INFO_USAGE_DATE_RECORD:
206         CopyMem (&mUserInfo.UsageDate, (UINT8 *) (Info + 1), DataLen);
207         mUserInfo.UsageDateExist = TRUE;
208         break;
209 
210       case EFI_USER_INFO_USAGE_COUNT_RECORD:
211         CopyMem (&mUserInfo.UsageCount, (UINT8 *) (Info + 1), DataLen);
212         break;
213 
214       case EFI_USER_INFO_ACCESS_POLICY_RECORD:
215         mUserInfo.AccessPolicy = AllocateZeroPool (DataLen);
216         if (mUserInfo.AccessPolicy == NULL) {
217           break;
218         }
219 
220         CopyMem (mUserInfo.AccessPolicy, (UINT8 *) (Info + 1), DataLen);
221         mUserInfo.AccessPolicyLen = DataLen;
222         break;
223 
224       case EFI_USER_INFO_IDENTITY_POLICY_RECORD:
225         mUserInfo.IdentityPolicy = AllocateZeroPool (DataLen);
226         if (mUserInfo.IdentityPolicy == NULL) {
227           break;
228         }
229 
230         CopyMem (mUserInfo.IdentityPolicy, (UINT8 *) (Info + 1), DataLen);
231         mUserInfo.IdentityPolicyLen = DataLen;
232         break;
233 
234       default:
235         break;
236       }
237     }
238   }
239   FreePool (Info);
240 }
241 
242 
243 /**
244   Convert the Date to a string, and update the Hii database DateID string with it.
245 
246   @param[in] Date       Points to the date to be converted.
247   @param[in] DateId     String ID in the HII database to be replaced.
248 
249 **/
250 VOID
ResolveDate(IN EFI_TIME * Date,IN EFI_STRING_ID DateId)251 ResolveDate (
252   IN EFI_TIME                                   *Date,
253   IN EFI_STRING_ID                              DateId
254   )
255 {
256   CHAR16  *Str;
257   UINTN   DateBufLen;
258 
259   //
260   // Convert date to string.
261   //
262   DateBufLen = 64;
263   Str        = AllocateZeroPool (DateBufLen);
264   if (Str == NULL) {
265     return ;
266   }
267 
268   UnicodeSPrint (
269     Str,
270     DateBufLen,
271     L"%4d-%2d-%2d ",
272     Date->Year,
273     Date->Month,
274     Date->Day
275     );
276 
277   //
278   // Convert time to string.
279   //
280   DateBufLen -= StrLen (Str);
281   UnicodeSPrint (
282     Str + StrLen (Str),
283     DateBufLen,
284     L"%2d:%2d:%2d",
285     Date->Hour,
286     Date->Minute,
287     Date->Second
288     );
289 
290   HiiSetString (mCallbackInfo->HiiHandle, DateId, Str, NULL);
291   FreePool (Str);
292 }
293 
294 
295 /**
296   Convert the CountVal to a string, and update the Hii database CountId string
297   with it.
298 
299   @param[in]  CountVal   The hex value to convert.
300   @param[in]  CountId    String ID in the HII database to be replaced.
301 
302 **/
303 VOID
ResolveCount(IN UINT32 CountVal,IN EFI_STRING_ID CountId)304 ResolveCount (
305   IN UINT32                                     CountVal,
306   IN EFI_STRING_ID                              CountId
307   )
308 {
309   CHAR16  Count[10];
310 
311   UnicodeSPrint (Count, 20, L"%d", CountVal);
312   HiiSetString (mCallbackInfo->HiiHandle, CountId, Count, NULL);
313 }
314 
315 
316 /**
317   Concatenates one Null-terminated Unicode string to another Null-terminated
318   Unicode string.
319 
320   @param[in, out]  Source1      On entry, point to a Null-terminated Unicode string.
321                                 On exit, point to a new concatenated Unicode string
322   @param[in]       Source2      Pointer to a Null-terminated Unicode string.
323 
324 **/
325 VOID
AddStr(IN OUT CHAR16 ** Source1,IN CONST CHAR16 * Source2)326 AddStr (
327   IN OUT  CHAR16                  **Source1,
328   IN      CONST CHAR16            *Source2
329   )
330 {
331   CHAR16                        *TmpStr;
332   UINTN                         StrLength;
333 
334   ASSERT (Source1 != NULL);
335   ASSERT (Source2 != NULL);
336 
337   if (*Source1 == NULL) {
338     StrLength = StrSize (Source2);
339   } else {
340     StrLength  = StrSize (*Source1);
341     StrLength += StrSize (Source2) - 2;
342   }
343 
344   TmpStr     = AllocateZeroPool (StrLength);
345   ASSERT (TmpStr != NULL);
346 
347   if (*Source1 == NULL) {
348     StrCpyS (TmpStr, StrLength / sizeof (CHAR16), Source2);
349   } else {
350     StrCpyS (TmpStr, StrLength / sizeof (CHAR16), *Source1);
351     FreePool (*Source1);
352     StrCatS (TmpStr, StrLength / sizeof (CHAR16),Source2);
353   }
354 
355   *Source1 = TmpStr;
356 }
357 
358 
359 /**
360   Convert the identity policy to a unicode string and update the Hii database
361   IpStringId string with it.
362 
363   @param[in]  Ip         Points to identity policy.
364   @param[in]  IpLen      The identity policy length.
365   @param[in]  IpStringId String ID in the HII database to be replaced.
366 
367 **/
368 VOID
ResolveIdentityPolicy(IN UINT8 * Ip,IN UINTN IpLen,IN EFI_STRING_ID IpStringId)369 ResolveIdentityPolicy (
370   IN  UINT8                                     *Ip,
371   IN  UINTN                                     IpLen,
372   IN  EFI_STRING_ID                             IpStringId
373   )
374 {
375   CHAR16                        *TmpStr;
376   UINTN                         ChkLen;
377   EFI_USER_INFO_IDENTITY_POLICY *Identity;
378   UINT16                        Index;
379   CHAR16                        *ProvStr;
380   EFI_STRING_ID                 ProvId;
381   EFI_HII_HANDLE                HiiHandle;
382   EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;
383 
384   TmpStr = NULL;
385 
386   //
387   // Resolve each policy.
388   //
389   ChkLen  = 0;
390   while (ChkLen < IpLen) {
391     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (Ip + ChkLen);
392     switch (Identity->Type) {
393     case EFI_USER_INFO_IDENTITY_FALSE:
394       AddStr (&TmpStr, L"False");
395       break;
396 
397     case EFI_USER_INFO_IDENTITY_TRUE:
398       AddStr (&TmpStr, L"None");
399       break;
400 
401     case EFI_USER_INFO_IDENTITY_NOT:
402       AddStr (&TmpStr, L"! ");
403       break;
404 
405     case EFI_USER_INFO_IDENTITY_AND:
406       AddStr (&TmpStr, L" && ");
407       break;
408 
409     case EFI_USER_INFO_IDENTITY_OR:
410       AddStr (&TmpStr, L" || ");
411       break;
412 
413     case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
414       for (Index = 0; Index < mProviderInfo->Count; Index++) {
415         UserCredential = mProviderInfo->Provider[Index];
416         if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Type)) {
417           UserCredential->Title (
418                             UserCredential,
419                             &HiiHandle,
420                             &ProvId
421                             );
422           ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
423           if (ProvStr != NULL) {
424             AddStr (&TmpStr, ProvStr);
425             FreePool (ProvStr);
426           }
427           break;
428         }
429       }
430       break;
431 
432     case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
433       for (Index = 0; Index < mProviderInfo->Count; Index++) {
434         UserCredential = mProviderInfo->Provider[Index];
435         if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Identifier)) {
436           UserCredential->Title (
437                             UserCredential,
438                             &HiiHandle,
439                             &ProvId
440                             );
441           ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
442           if (ProvStr != NULL) {
443             AddStr (&TmpStr, ProvStr);
444             FreePool (ProvStr);
445           }
446           break;
447         }
448       }
449       break;
450     }
451 
452     ChkLen += Identity->Length;
453   }
454 
455   if (TmpStr != NULL) {
456     HiiSetString (mCallbackInfo->HiiHandle, IpStringId, TmpStr, NULL);
457     FreePool (TmpStr);
458   }
459 }
460 
461 
462 /**
463   Display modify user information form.
464 
465   This form displays, username, create Date, usage date, usage count, identity policy,
466   and access policy.
467 
468   @param[in] UserIndex       The index of the user in display list to modify.
469 
470 **/
471 VOID
ModifyUserInfo(IN UINT8 UserIndex)472 ModifyUserInfo (
473   IN UINT8                                      UserIndex
474   )
475 {
476   EFI_STATUS               Status;
477   EFI_USER_PROFILE_HANDLE  CurrentUser;
478   UINT32                   CurrentAccessRight;
479   VOID                     *StartOpCodeHandle;
480   VOID                     *EndOpCodeHandle;
481   EFI_IFR_GUID_LABEL       *StartLabel;
482   EFI_IFR_GUID_LABEL       *EndLabel;
483 
484   //
485   // Initialize the container for dynamic opcodes.
486   //
487   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
488   ASSERT (StartOpCodeHandle != NULL);
489 
490   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
491   ASSERT (EndOpCodeHandle != NULL);
492 
493   //
494   // Create Hii Extend Label OpCode.
495   //
496   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
497                                         StartOpCodeHandle,
498                                         &gEfiIfrTianoGuid,
499                                         NULL,
500                                         sizeof (EFI_IFR_GUID_LABEL)
501                                         );
502   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
503   StartLabel->Number        = LABEL_USER_INFO_FUNC;
504 
505   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
506                                       EndOpCodeHandle,
507                                       &gEfiIfrTianoGuid,
508                                       NULL,
509                                       sizeof (EFI_IFR_GUID_LABEL)
510                                       );
511   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
512   EndLabel->Number        = LABEL_END;
513 
514   //
515   // Find the user profile to be modified.
516   //
517   mModifyUser = NULL;
518   Status      = mUserManager->GetNext (mUserManager, &mModifyUser);
519   if (EFI_ERROR (Status)) {
520     return ;
521   }
522 
523   while (UserIndex > 1) {
524     Status = mUserManager->GetNext (mUserManager, &mModifyUser);
525     if (EFI_ERROR (Status)) {
526       return ;
527     }
528     UserIndex--;
529   }
530 
531   //
532   // Get user profile information.
533   //
534   GetAllUserInfo ();
535 
536   //
537   // Update user name.
538   HiiSetString (
539     mCallbackInfo->HiiHandle,
540     STRING_TOKEN (STR_USER_NAME_VAL),
541     mUserInfo.UserName,
542     NULL
543     );
544 
545   //
546   // Update create date.
547   //
548   if (mUserInfo.CreateDateExist) {
549     ResolveDate (&mUserInfo.CreateDate, STRING_TOKEN (STR_CREATE_DATE_VAL));
550   } else {
551     HiiSetString (
552       mCallbackInfo->HiiHandle,
553       STRING_TOKEN (STR_CREATE_DATE_VAL),
554       L"",
555       NULL
556       );
557   }
558 
559   //
560   // Add usage date.
561   //
562   if (mUserInfo.UsageDateExist) {
563     ResolveDate (&mUserInfo.UsageDate, STRING_TOKEN (STR_USAGE_DATE_VAL));
564   } else {
565     HiiSetString (
566       mCallbackInfo->HiiHandle,
567       STRING_TOKEN (STR_USAGE_DATE_VAL),
568       L"",
569       NULL
570       );
571   }
572 
573   //
574   // Add usage count.
575   //
576   ResolveCount ((UINT32) mUserInfo.UsageCount, STRING_TOKEN (STR_USAGE_COUNT_VAL));
577 
578   //
579   // Add identity policy.
580   //
581   mUserManager->Current (mUserManager, &CurrentUser);
582   if (mModifyUser == CurrentUser) {
583     ResolveIdentityPolicy (
584       mUserInfo.IdentityPolicy,
585       mUserInfo.IdentityPolicyLen,
586       STRING_TOKEN (STR_IDENTIFY_POLICY_VAL)
587       );
588     HiiCreateGotoOpCode (
589       StartOpCodeHandle,                                  // Container for opcodes
590       FORMID_MODIFY_IP,                                   // Target Form ID
591       STRING_TOKEN (STR_IDENTIFY_POLICY),                 // Prompt text
592       STRING_TOKEN (STR_IDENTIFY_POLICY_VAL),             // Help text
593       EFI_IFR_FLAG_CALLBACK,                              // Question flag
594       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP   // Question ID
595       );
596   }
597 
598   //
599   // Add access policy.
600   //
601   Status = GetAccessRight (&CurrentAccessRight);
602   if (EFI_ERROR (Status)) {
603     CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
604   }
605 
606   if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
607     HiiCreateGotoOpCode (
608       StartOpCodeHandle,                                  // Container for opcodes
609       FORMID_MODIFY_AP,                                   // Target Form ID
610       STRING_TOKEN (STR_ACCESS_POLICY),                   // Prompt text
611       STRING_TOKEN (STR_NULL_STRING),                     // Help text
612       EFI_IFR_FLAG_CALLBACK,                              // Question flag
613       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP   // Question ID
614       );
615   }
616 
617   HiiUpdateForm (
618     mCallbackInfo->HiiHandle,                             // HII handle
619     &gUserProfileManagerGuid,                             // Formset GUID
620     FORMID_USER_INFO,                                     // Form ID
621     StartOpCodeHandle,                                    // Label
622     EndOpCodeHandle                                       // Replace data
623     );
624 
625   HiiFreeOpCodeHandle (StartOpCodeHandle);
626   HiiFreeOpCodeHandle (EndOpCodeHandle);
627 }
628 
629 
630 /**
631   Get all the access policy info from current user info, and save in the global
632   variable.
633 
634 **/
635 VOID
ResolveAccessPolicy(VOID)636 ResolveAccessPolicy (
637   VOID
638   )
639 {
640   UINTN                         OffSet;
641   EFI_USER_INFO_ACCESS_CONTROL  Control;
642   UINTN                         ValLen;
643   UINT8                         *AccessData;
644 
645   //
646   // Set default value
647   //
648   mAccessInfo.AccessRight       = EFI_USER_INFO_ACCESS_ENROLL_SELF;
649   mAccessInfo.AccessSetup       = ACCESS_SETUP_RESTRICTED;
650   mAccessInfo.AccessBootOrder   = EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT;
651 
652   mAccessInfo.LoadPermitLen     = 0;
653   mAccessInfo.LoadForbidLen     = 0;
654   mAccessInfo.ConnectPermitLen  = 0;
655   mAccessInfo.ConnectForbidLen  = 0;
656 
657   //
658   // Get each user access policy.
659   //
660   OffSet = 0;
661   while (OffSet < mUserInfo.AccessPolicyLen) {
662     CopyMem (&Control, mUserInfo.AccessPolicy + OffSet, sizeof (Control));
663     ValLen = Control.Size - sizeof (Control);
664     switch (Control.Type) {
665     case EFI_USER_INFO_ACCESS_ENROLL_SELF:
666       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
667       break;
668 
669     case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:
670       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_OTHERS;
671       break;
672 
673     case EFI_USER_INFO_ACCESS_MANAGE:
674       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_MANAGE;
675       break;
676 
677     case EFI_USER_INFO_ACCESS_SETUP:
678       AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
679       if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupNormalGuid)) {
680         mAccessInfo.AccessSetup = ACCESS_SETUP_NORMAL;
681       } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupRestrictedGuid)) {
682         mAccessInfo.AccessSetup = ACCESS_SETUP_RESTRICTED;
683       } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupAdminGuid)) {
684         mAccessInfo.AccessSetup = ACCESS_SETUP_ADMIN;
685       }
686       break;
687 
688     case EFI_USER_INFO_ACCESS_BOOT_ORDER:
689       AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
690       CopyMem (&mAccessInfo.AccessBootOrder, AccessData, sizeof (UINT32));
691       break;
692 
693     case EFI_USER_INFO_ACCESS_FORBID_LOAD:
694       if (mAccessInfo.LoadForbid != NULL) {
695         FreePool (mAccessInfo.LoadForbid);
696       }
697 
698       mAccessInfo.LoadForbid = AllocateZeroPool (ValLen);
699       if (mAccessInfo.LoadForbid != NULL) {
700         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
701         CopyMem (mAccessInfo.LoadForbid, AccessData, ValLen);
702         mAccessInfo.LoadForbidLen = ValLen;
703       }
704       break;
705 
706     case EFI_USER_INFO_ACCESS_PERMIT_LOAD:
707       if (mAccessInfo.LoadPermit != NULL) {
708         FreePool (mAccessInfo.LoadPermit);
709       }
710 
711       mAccessInfo.LoadPermit = AllocateZeroPool (ValLen);
712       if (mAccessInfo.LoadPermit != NULL) {
713         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
714         CopyMem (mAccessInfo.LoadPermit, AccessData, ValLen);
715         mAccessInfo.LoadPermitLen = ValLen;
716       }
717       break;
718 
719     case EFI_USER_INFO_ACCESS_FORBID_CONNECT:
720       if (mAccessInfo.ConnectForbid != NULL) {
721         FreePool (mAccessInfo.ConnectForbid);
722       }
723 
724       mAccessInfo.ConnectForbid = AllocateZeroPool (ValLen);
725       if (mAccessInfo.ConnectForbid != NULL) {
726         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
727         CopyMem (mAccessInfo.ConnectForbid, AccessData, ValLen);
728         mAccessInfo.ConnectForbidLen = ValLen;
729       }
730       break;
731 
732     case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:
733       if (mAccessInfo.ConnectPermit != NULL) {
734         FreePool (mAccessInfo.ConnectPermit);
735       }
736 
737       mAccessInfo.ConnectPermit = AllocateZeroPool (ValLen);
738       if (mAccessInfo.ConnectPermit != NULL) {
739         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
740         CopyMem (mAccessInfo.ConnectPermit, AccessData, ValLen);
741         mAccessInfo.ConnectPermitLen = ValLen;
742       }
743       break;
744     }
745 
746     OffSet += Control.Size;
747   }
748 }
749 
750 
751 /**
752   Find the specified info in User profile by the InfoType.
753 
754   @param[in]  User         Handle of the user whose information will be searched.
755   @param[in]  InfoType     The user information type to find.
756   @param[out] UserInfo     Points to user information handle found.
757 
758   @retval EFI_SUCCESS      Find the user information successfully.
759   @retval Others           Fail to find the user information.
760 
761 **/
762 EFI_STATUS
FindInfoByType(IN EFI_USER_PROFILE_HANDLE User,IN UINT8 InfoType,OUT EFI_USER_INFO_HANDLE * UserInfo)763 FindInfoByType (
764   IN  EFI_USER_PROFILE_HANDLE                   User,
765   IN  UINT8                                     InfoType,
766   OUT EFI_USER_INFO_HANDLE                      *UserInfo
767   )
768 {
769   EFI_STATUS    Status;
770   EFI_USER_INFO *Info;
771   UINTN         InfoSize;
772   UINTN         MemSize;
773 
774   if (UserInfo == NULL) {
775     return EFI_INVALID_PARAMETER;
776   }
777 
778   *UserInfo = NULL;
779   //
780   // Allocate user information memory.
781   //
782   MemSize = sizeof (EFI_USER_INFO) + 63;
783   Info    = AllocateZeroPool (MemSize);
784   if (Info == NULL) {
785     return EFI_OUT_OF_RESOURCES;
786   }
787 
788   //
789   // Get each user information.
790   //
791   while (TRUE) {
792     Status = mUserManager->GetNextInfo (mUserManager, User, UserInfo);
793     if (EFI_ERROR (Status)) {
794       break;
795     }
796     //
797     // Get information.
798     //
799     InfoSize  = MemSize;
800     Status    = mUserManager->GetInfo (
801                                 mUserManager,
802                                 User,
803                                 *UserInfo,
804                                 Info,
805                                 &InfoSize
806                                 );
807     if (Status == EFI_BUFFER_TOO_SMALL) {
808       MemSize = InfoSize;
809       FreePool (Info);
810       Info = AllocateZeroPool (MemSize);
811       if (Info == NULL) {
812         return EFI_OUT_OF_RESOURCES;
813       }
814       Status = mUserManager->GetInfo (
815                                mUserManager,
816                                User,
817                                *UserInfo,
818                                Info,
819                                &InfoSize
820                                );
821     }
822     if (Status == EFI_SUCCESS) {
823       if (Info->InfoType == InfoType) {
824         break;
825       }
826     }
827   }
828 
829   FreePool (Info);
830   return Status;
831 }
832 
833 
834 /**
835   Display modify user access policy form.
836 
837   In this form, access right, access setup and access boot order are dynamically
838   added. Load devicepath and connect devicepath are displayed too.
839 
840 **/
841 VOID
ModidyAccessPolicy(VOID)842 ModidyAccessPolicy (
843   VOID
844   )
845 {
846   VOID                *StartOpCodeHandle;
847   VOID                *EndOpCodeHandle;
848   VOID                *OptionsOpCodeHandle;
849   EFI_IFR_GUID_LABEL  *StartLabel;
850   EFI_IFR_GUID_LABEL  *EndLabel;
851   VOID                *DefaultOpCodeHandle;
852 
853   //
854   // Initialize the container for dynamic opcodes.
855   //
856   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
857   ASSERT (StartOpCodeHandle != NULL);
858 
859   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
860   ASSERT (EndOpCodeHandle != NULL);
861 
862   //
863   // Create Hii Extend Label OpCode.
864   //
865   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
866                                         StartOpCodeHandle,
867                                         &gEfiIfrTianoGuid,
868                                         NULL,
869                                         sizeof (EFI_IFR_GUID_LABEL)
870                                         );
871   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
872   StartLabel->Number        = LABEL_AP_MOD_FUNC;
873 
874   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
875                                       EndOpCodeHandle,
876                                       &gEfiIfrTianoGuid,
877                                       NULL,
878                                       sizeof (EFI_IFR_GUID_LABEL)
879                                       );
880   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
881   EndLabel->Number        = LABEL_END;
882 
883 
884   //
885   // Resolve access policy information.
886   //
887   ResolveAccessPolicy ();
888 
889   //
890   // Add access right one-of-code.
891   //
892   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
893   ASSERT (OptionsOpCodeHandle != NULL);
894   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
895   ASSERT (DefaultOpCodeHandle != NULL);
896 
897   HiiCreateOneOfOptionOpCode (
898     OptionsOpCodeHandle,
899     STRING_TOKEN (STR_NORMAL),
900     0,
901     EFI_IFR_NUMERIC_SIZE_1,
902     EFI_USER_INFO_ACCESS_ENROLL_SELF
903     );
904 
905   HiiCreateOneOfOptionOpCode (
906     OptionsOpCodeHandle,
907     STRING_TOKEN (STR_ENROLL),
908     0,
909     EFI_IFR_NUMERIC_SIZE_1,
910     EFI_USER_INFO_ACCESS_ENROLL_OTHERS
911     );
912 
913   HiiCreateOneOfOptionOpCode (
914     OptionsOpCodeHandle,
915     STRING_TOKEN (STR_MANAGE),
916     0,
917     EFI_IFR_NUMERIC_SIZE_1,
918     EFI_USER_INFO_ACCESS_MANAGE
919     );
920 
921   HiiCreateDefaultOpCode (
922     DefaultOpCodeHandle,
923     EFI_HII_DEFAULT_CLASS_STANDARD,
924     EFI_IFR_NUMERIC_SIZE_1,
925     mAccessInfo.AccessRight
926     );
927 
928   HiiCreateOneOfOpCode (
929     StartOpCodeHandle,                    // Container for dynamic created opcodes
930     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_RIGHT, // Question ID
931     0,                                    // VarStore ID
932     0,                                    // Offset in Buffer Storage
933     STRING_TOKEN (STR_ACCESS_RIGHT),      // Question prompt text
934     STRING_TOKEN (STR_ACCESS_RIGHT_HELP), // Question help text
935     EFI_IFR_FLAG_CALLBACK,                // Question flag
936     EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
937     OptionsOpCodeHandle,                  // Option Opcode list
938     DefaultOpCodeHandle                   // Default Opcode
939     );
940   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
941   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
942 
943 
944   //
945   // Add setup type one-of-code.
946   //
947   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
948   ASSERT (OptionsOpCodeHandle != NULL);
949   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
950   ASSERT (DefaultOpCodeHandle != NULL);
951 
952   HiiCreateOneOfOptionOpCode (
953     OptionsOpCodeHandle,
954     STRING_TOKEN (STR_RESTRICTED),
955     0,
956     EFI_IFR_NUMERIC_SIZE_1,
957     ACCESS_SETUP_RESTRICTED
958     );
959 
960   HiiCreateOneOfOptionOpCode (
961     OptionsOpCodeHandle,
962     STRING_TOKEN (STR_NORMAL),
963     0,
964     EFI_IFR_NUMERIC_SIZE_1,
965     ACCESS_SETUP_NORMAL
966     );
967 
968   HiiCreateOneOfOptionOpCode (
969     OptionsOpCodeHandle,
970     STRING_TOKEN (STR_ADMIN),
971     0,
972     EFI_IFR_NUMERIC_SIZE_1,
973     ACCESS_SETUP_ADMIN
974     );
975 
976   HiiCreateDefaultOpCode (
977     DefaultOpCodeHandle,
978     EFI_HII_DEFAULT_CLASS_STANDARD,
979     EFI_IFR_NUMERIC_SIZE_1,
980     mAccessInfo.AccessSetup
981     );
982 
983   HiiCreateOneOfOpCode (
984     StartOpCodeHandle,                    // Container for dynamic created opcodes
985     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_SETUP, // Question ID
986     0,                                    // VarStore ID
987     0,                                    // Offset in Buffer Storage
988     STRING_TOKEN (STR_ACCESS_SETUP),      // Question prompt text
989     STRING_TOKEN (STR_ACCESS_SETUP_HELP), // Question help text
990     EFI_IFR_FLAG_CALLBACK,                // Question flag
991     EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
992     OptionsOpCodeHandle,                  // Option Opcode list
993     DefaultOpCodeHandle                   // Default Opcode
994     );
995   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
996   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
997 
998   //
999   // Add boot order one-of-code.
1000   //
1001   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1002   ASSERT (OptionsOpCodeHandle != NULL);
1003   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
1004   ASSERT (DefaultOpCodeHandle != NULL);
1005 
1006   HiiCreateOneOfOptionOpCode (
1007     OptionsOpCodeHandle,
1008     STRING_TOKEN (STR_INSERT),
1009     0,
1010     EFI_IFR_NUMERIC_SIZE_4,
1011     EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT
1012     );
1013 
1014   HiiCreateOneOfOptionOpCode (
1015     OptionsOpCodeHandle,
1016     STRING_TOKEN (STR_APPEND),
1017     0,
1018     EFI_IFR_NUMERIC_SIZE_4,
1019     EFI_USER_INFO_ACCESS_BOOT_ORDER_APPEND
1020     );
1021 
1022   HiiCreateOneOfOptionOpCode (
1023     OptionsOpCodeHandle,
1024     STRING_TOKEN (STR_REPLACE),
1025     0,
1026     EFI_IFR_NUMERIC_SIZE_4,
1027     EFI_USER_INFO_ACCESS_BOOT_ORDER_REPLACE
1028     );
1029 
1030   HiiCreateOneOfOptionOpCode (
1031     OptionsOpCodeHandle,
1032     STRING_TOKEN (STR_NODEFAULT),
1033     0,
1034     EFI_IFR_NUMERIC_SIZE_4,
1035     EFI_USER_INFO_ACCESS_BOOT_ORDER_NODEFAULT
1036     );
1037 
1038   HiiCreateDefaultOpCode (
1039     DefaultOpCodeHandle,
1040     EFI_HII_DEFAULT_CLASS_STANDARD,
1041     EFI_IFR_NUMERIC_SIZE_4,
1042     mAccessInfo.AccessBootOrder
1043     );
1044 
1045   HiiCreateOneOfOpCode (
1046     StartOpCodeHandle,                  // Container for dynamic created opcodes
1047     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_BOOT, // Question ID
1048     0,                                  // VarStore ID
1049     0,                                  // Offset in Buffer Storage
1050     STRING_TOKEN (STR_BOOR_ORDER),      // Question prompt text
1051     STRING_TOKEN (STR_BOOT_ORDER_HELP), // Question help text
1052     EFI_IFR_FLAG_CALLBACK,              // Question flag
1053     EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
1054     OptionsOpCodeHandle,                // Option Opcode list
1055     DefaultOpCodeHandle                 // Default Opcode
1056     );
1057   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
1058   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1059 
1060   //
1061   // Update Form.
1062   //
1063   HiiUpdateForm (
1064     mCallbackInfo->HiiHandle,           // HII handle
1065     &gUserProfileManagerGuid,           // Formset GUID
1066     FORMID_MODIFY_AP,                   // Form ID
1067     StartOpCodeHandle,                  // Label for where to insert opcodes
1068     EndOpCodeHandle                     // Replace data
1069     );
1070 
1071   HiiFreeOpCodeHandle (StartOpCodeHandle);
1072   HiiFreeOpCodeHandle (EndOpCodeHandle);
1073 }
1074 
1075 
1076 /**
1077   Expand access policy memory size.
1078 
1079   @param[in] ValidLen       The valid access policy length.
1080   @param[in] ExpandLen      The length that is needed to expand.
1081 
1082 **/
1083 VOID
ExpandMemory(IN UINTN ValidLen,IN UINTN ExpandLen)1084 ExpandMemory (
1085   IN      UINTN                                 ValidLen,
1086   IN      UINTN                                 ExpandLen
1087   )
1088 {
1089   UINT8 *Mem;
1090   UINTN Len;
1091 
1092   //
1093   // Expand memory.
1094   //
1095   Len = mUserInfo.AccessPolicyLen + (ExpandLen / 64 + 1) * 64;
1096   Mem = AllocateZeroPool (Len);
1097   ASSERT (Mem != NULL);
1098 
1099   if (mUserInfo.AccessPolicy != NULL) {
1100     CopyMem (Mem, mUserInfo.AccessPolicy, ValidLen);
1101     FreePool (mUserInfo.AccessPolicy);
1102   }
1103 
1104   mUserInfo.AccessPolicy    = Mem;
1105   mUserInfo.AccessPolicyLen = Len;
1106 }
1107 
1108 
1109 /**
1110   Get the username from user input, and update username string in the Hii
1111   database with it.
1112 
1113 **/
1114 VOID
ModifyUserName(VOID)1115 ModifyUserName (
1116   VOID
1117   )
1118 {
1119   EFI_STATUS              Status;
1120   CHAR16                  UserName[USER_NAME_LENGTH];
1121   UINTN                   Len;
1122   EFI_INPUT_KEY           Key;
1123   EFI_USER_INFO_HANDLE    UserInfo;
1124   EFI_USER_INFO           *Info;
1125   EFI_USER_PROFILE_HANDLE TempUser;
1126 
1127   //
1128   // Get the new user name.
1129   //
1130   Len = sizeof (UserName);
1131   Status = GetUserNameInput (&Len, UserName);
1132   if (EFI_ERROR (Status)) {
1133     if (Status != EFI_ABORTED) {
1134       CreatePopUp (
1135         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1136         &Key,
1137         L"Failed To Get User Name.",
1138         L"",
1139         L"Please Press Any Key to Continue ...",
1140         NULL
1141         );
1142     }
1143     return ;
1144   }
1145 
1146   //
1147   // Check whether the username had been used or not.
1148   //
1149   Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + Len);
1150   if (Info == NULL) {
1151     return ;
1152   }
1153 
1154   Info->InfoType    = EFI_USER_INFO_NAME_RECORD;
1155   Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
1156                       EFI_USER_INFO_PUBLIC |
1157                       EFI_USER_INFO_EXCLUSIVE;
1158   Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + Len);
1159   CopyMem ((UINT8 *) (Info + 1), UserName, Len);
1160 
1161   TempUser  = NULL;
1162   Status    = mUserManager->Find (
1163                               mUserManager,
1164                               &TempUser,
1165                               NULL,
1166                               Info,
1167                               Info->InfoSize
1168                               );
1169   if (!EFI_ERROR (Status)) {
1170     CreatePopUp (
1171       EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1172       &Key,
1173       L"The User Name Had Been Used.",
1174       L"",
1175       L"Please Use Other User Name",
1176       NULL
1177       );
1178     FreePool (Info);
1179     return ;
1180   }
1181 
1182   //
1183   // Update username display in the form.
1184   //
1185   CopyMem (mUserInfo.UserName, UserName, Len);
1186   HiiSetString (
1187     mCallbackInfo->HiiHandle,
1188     STRING_TOKEN (STR_USER_NAME_VAL),
1189     mUserInfo.UserName,
1190     NULL
1191     );
1192 
1193   //
1194   // Save the user name.
1195   //
1196   Status = FindInfoByType (mModifyUser, EFI_USER_INFO_NAME_RECORD, &UserInfo);
1197   if (!EFI_ERROR (Status)) {
1198     mUserManager->SetInfo (
1199                     mUserManager,
1200                     mModifyUser,
1201                     &UserInfo,
1202                     Info,
1203                     Info->InfoSize
1204                     );
1205   }
1206   FreePool (Info);
1207 }
1208 
1209 
1210 /**
1211   Display the form of the modifying user identity policy.
1212 
1213 **/
1214 VOID
ModifyIdentityPolicy(VOID)1215 ModifyIdentityPolicy (
1216   VOID
1217   )
1218 {
1219   UINTN               Index;
1220   CHAR16              *ProvStr;
1221   EFI_STRING_ID       ProvID;
1222   EFI_HII_HANDLE      HiiHandle;
1223   VOID                *OptionsOpCodeHandle;
1224   VOID                *StartOpCodeHandle;
1225   VOID                *EndOpCodeHandle;
1226   EFI_IFR_GUID_LABEL  *StartLabel;
1227   EFI_IFR_GUID_LABEL  *EndLabel;
1228 
1229   //
1230   // Initialize the container for dynamic opcodes.
1231   //
1232   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1233   ASSERT (StartOpCodeHandle != NULL);
1234 
1235   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1236   ASSERT (EndOpCodeHandle != NULL);
1237 
1238   //
1239   // Create Hii Extend Label OpCode.
1240   //
1241   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1242                                         StartOpCodeHandle,
1243                                         &gEfiIfrTianoGuid,
1244                                         NULL,
1245                                         sizeof (EFI_IFR_GUID_LABEL)
1246                                         );
1247   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
1248   StartLabel->Number        = LABEL_IP_MOD_FUNC;
1249 
1250   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1251                                       EndOpCodeHandle,
1252                                       &gEfiIfrTianoGuid,
1253                                       NULL,
1254                                       sizeof (EFI_IFR_GUID_LABEL)
1255                                       );
1256   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
1257   EndLabel->Number        = LABEL_END;
1258 
1259   //
1260   // Add credential providers
1261   //.
1262   if (mProviderInfo->Count > 0) {
1263     OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1264     ASSERT (OptionsOpCodeHandle != NULL);
1265 
1266     //
1267     // Add credential provider Option OpCode.
1268     //
1269     for (Index = 0; Index < mProviderInfo->Count; Index++) {
1270       mProviderInfo->Provider[Index]->Title (
1271                                         mProviderInfo->Provider[Index],
1272                                         &HiiHandle,
1273                                         &ProvID
1274                                         );
1275       ProvStr = HiiGetString (HiiHandle, ProvID, NULL);
1276       ProvID  = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);
1277       FreePool (ProvStr);
1278       if (ProvID == 0) {
1279         return ;
1280       }
1281 
1282       HiiCreateOneOfOptionOpCode (
1283         OptionsOpCodeHandle,
1284         ProvID,
1285         0,
1286         EFI_IFR_NUMERIC_SIZE_1,
1287         (UINT8) Index
1288         );
1289     }
1290 
1291     HiiCreateOneOfOpCode (
1292       StartOpCodeHandle,                // Container for dynamic created opcodes
1293       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_PROV,  // Question ID
1294       0,                                // VarStore ID
1295       0,                                // Offset in Buffer Storage
1296       STRING_TOKEN (STR_PROVIDER),      // Question prompt text
1297       STRING_TOKEN (STR_PROVIDER_HELP), // Question help text
1298       EFI_IFR_FLAG_CALLBACK,            // Question flag
1299       EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
1300       OptionsOpCodeHandle,              // Option Opcode list
1301       NULL                              // Default Opcode is NULl
1302       );
1303 
1304     HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1305   }
1306 
1307   //
1308   // Add logical connector Option OpCode.
1309   //
1310   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1311   ASSERT (OptionsOpCodeHandle != NULL);
1312 
1313   HiiCreateOneOfOptionOpCode (
1314     OptionsOpCodeHandle,
1315     STRING_TOKEN (STR_AND_CON),
1316     0,
1317     EFI_IFR_NUMERIC_SIZE_1,
1318     0
1319     );
1320 
1321   HiiCreateOneOfOptionOpCode (
1322     OptionsOpCodeHandle,
1323     STRING_TOKEN (STR_OR_CON),
1324     0,
1325     EFI_IFR_NUMERIC_SIZE_1,
1326     1
1327     );
1328 
1329   HiiCreateOneOfOpCode (
1330     StartOpCodeHandle,                  // Container for dynamic created opcodes
1331     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_CONN,  // Question ID
1332     0,                                  // VarStore ID
1333     0,                                  // Offset in Buffer Storage
1334     STRING_TOKEN (STR_CONNECTOR),       // Question prompt text
1335     STRING_TOKEN (STR_CONNECTOR_HELP),  // Question help text
1336     EFI_IFR_FLAG_CALLBACK,              // Question flag
1337     EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
1338     OptionsOpCodeHandle,                // Option Opcode list
1339     NULL                                // Default Opcode is NULl
1340     );
1341 
1342   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1343 
1344   //
1345   // Update identity policy in the form.
1346   //
1347   ResolveIdentityPolicy (
1348     mUserInfo.IdentityPolicy,
1349     mUserInfo.IdentityPolicyLen,
1350     STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE)
1351     );
1352 
1353   if (mUserInfo.NewIdentityPolicy != NULL) {
1354     FreePool (mUserInfo.NewIdentityPolicy);
1355     mUserInfo.NewIdentityPolicy         = NULL;
1356     mUserInfo.NewIdentityPolicyLen      = 0;
1357     mUserInfo.NewIdentityPolicyModified = FALSE;
1358   }
1359   mProviderChoice = 0;
1360   mConncetLogical = 0;
1361 
1362   HiiUpdateForm (
1363     mCallbackInfo->HiiHandle, // HII handle
1364     &gUserProfileManagerGuid, // Formset GUID
1365     FORMID_MODIFY_IP,         // Form ID
1366     StartOpCodeHandle,        // Label for where to insert opcodes
1367     EndOpCodeHandle           // Replace data
1368     );
1369 
1370   HiiFreeOpCodeHandle (StartOpCodeHandle);
1371   HiiFreeOpCodeHandle (EndOpCodeHandle);
1372 }
1373 
1374 
1375 /**
1376   Get current user's access right.
1377 
1378   @param[out]  AccessRight  Points to the buffer used for user's access right.
1379 
1380   @retval EFI_SUCCESS       Get current user access right successfully.
1381   @retval others            Fail to get current user access right.
1382 
1383 **/
1384 EFI_STATUS
GetAccessRight(OUT UINT32 * AccessRight)1385 GetAccessRight (
1386   OUT  UINT32                                    *AccessRight
1387   )
1388 {
1389   EFI_STATUS                    Status;
1390   EFI_USER_INFO_HANDLE          UserInfo;
1391   EFI_USER_INFO                 *Info;
1392   UINTN                         InfoSize;
1393   UINTN                         MemSize;
1394   EFI_USER_INFO_ACCESS_CONTROL  Access;
1395   EFI_USER_PROFILE_HANDLE       CurrentUser;
1396   UINTN                         TotalLen;
1397   UINTN                         CheckLen;
1398 
1399   //
1400   // Allocate user information memory.
1401   //
1402   MemSize = sizeof (EFI_USER_INFO) + 63;
1403   Info    = AllocateZeroPool (MemSize);
1404   if (Info == NULL) {
1405     return EFI_OUT_OF_RESOURCES;
1406   }
1407 
1408   //
1409   // Get user access information.
1410   //
1411   UserInfo = NULL;
1412   mUserManager->Current (mUserManager, &CurrentUser);
1413   while (TRUE) {
1414     InfoSize = MemSize;
1415     //
1416     // Get next user information.
1417     //
1418     Status = mUserManager->GetNextInfo (mUserManager, CurrentUser, &UserInfo);
1419     if (EFI_ERROR (Status)) {
1420       break;
1421     }
1422 
1423     Status = mUserManager->GetInfo (
1424                              mUserManager,
1425                              CurrentUser,
1426                              UserInfo,
1427                              Info,
1428                              &InfoSize
1429                              );
1430     if (Status == EFI_BUFFER_TOO_SMALL) {
1431       MemSize = InfoSize;
1432       FreePool (Info);
1433       Info = AllocateZeroPool (MemSize);
1434       if (Info == NULL) {
1435         return EFI_OUT_OF_RESOURCES;
1436       }
1437       Status = mUserManager->GetInfo (
1438                                mUserManager,
1439                                CurrentUser,
1440                                UserInfo,
1441                                Info,
1442                                &InfoSize
1443                                );
1444     }
1445     if (EFI_ERROR (Status)) {
1446       break;
1447     }
1448 
1449     //
1450     // Check user information.
1451     //
1452     if (Info->InfoType == EFI_USER_INFO_ACCESS_POLICY_RECORD) {
1453       TotalLen  = Info->InfoSize - sizeof (EFI_USER_INFO);
1454       CheckLen  = 0;
1455       //
1456       // Get specified access information.
1457       //
1458       while (CheckLen < TotalLen) {
1459         CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));
1460         if ((Access.Type == EFI_USER_INFO_ACCESS_ENROLL_SELF) ||
1461             (Access.Type == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) ||
1462             (Access.Type == EFI_USER_INFO_ACCESS_MANAGE)
1463             ) {
1464           *AccessRight = Access.Type;
1465           FreePool (Info);
1466           return EFI_SUCCESS;
1467         }
1468         CheckLen += Access.Size;
1469       }
1470     }
1471   }
1472   FreePool (Info);
1473   return EFI_NOT_FOUND;
1474 }
1475 
1476